From 83b88bd75958f6ebcdea78ff0da7d83f6555923c Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Fri, 24 Mar 2023 14:46:07 -0400 Subject: [PATCH 1/6] feat: complete view for styles --- client/package-lock.json | 123 ++++++++++++++++++++-- client/package.json | 3 +- client/src/components/Main/BingStyles.jsx | 51 +++++++++ client/src/components/Main/RowButton.jsx | 16 +++ client/src/components/Main/TextChat.jsx | 47 ++++----- client/src/style.css | 35 ++++++ client/tailwind.config.js | 1 + 7 files changed, 239 insertions(+), 37 deletions(-) create mode 100644 client/src/components/Main/BingStyles.jsx create mode 100644 client/src/components/Main/RowButton.jsx diff --git a/client/package-lock.json b/client/package-lock.json index 56ccd4ec6c..bcf2e1b701 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -13,7 +13,7 @@ "@radix-ui/react-dialog": "^1.0.2", "@radix-ui/react-dropdown-menu": "^2.0.2", "@radix-ui/react-label": "^2.0.0", - "@radix-ui/react-tabs": "^1.0.2", + "@radix-ui/react-tabs": "^1.0.3", "@reduxjs/toolkit": "^1.9.2", "axios": "^1.3.4", "class-variance-authority": "^0.4.0", @@ -41,6 +41,7 @@ "swr": "^2.0.3", "tailwind-merge": "^1.9.1", "tailwindcss-animate": "^1.0.5", + "tailwindcss-radix": "^2.8.0", "url": "^0.11.0", "uuidv4": "^6.2.13" }, @@ -2897,9 +2898,9 @@ } }, "node_modules/@radix-ui/react-tabs": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.0.2.tgz", - "integrity": "sha512-gOUwh+HbjCuL0UCo8kZ+kdUEG8QtpdO4sMQduJ34ZEz0r4922g9REOBM+vIsfwtGxSug4Yb1msJMJYN2Bk8TpQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.0.3.tgz", + "integrity": "sha512-4CkF/Rx1GcrusI/JZ1Rvyx4okGUs6wEenWA0RG/N+CwkRhTy7t54y7BLsWUXrAz/GRbBfHQg/Odfs/RoW0CiRA==", "dependencies": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.0", @@ -2907,8 +2908,58 @@ "@radix-ui/react-direction": "1.0.0", "@radix-ui/react-id": "1.0.0", "@radix-ui/react-presence": "1.0.0", - "@radix-ui/react-primitive": "1.0.1", - "@radix-ui/react-roving-focus": "1.0.2", + "@radix-ui/react-primitive": "1.0.2", + "@radix-ui/react-roving-focus": "1.0.3", + "@radix-ui/react-use-controllable-state": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.0.2.tgz", + "integrity": "sha512-s8WdQQ6wNXpaxdZ308KSr8fEWGrg4un8i4r/w7fhiS4ElRNjk5rRcl0/C6TANG2LvLOGIxtzo/jAg6Qf73TEBw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-primitive": "1.0.2", + "@radix-ui/react-slot": "1.0.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.2.tgz", + "integrity": "sha512-zY6G5Qq4R8diFPNwtyoLRZBxzu1Z+SXMlfYpChN7Dv8gvmx9X3qhDqiLWvKseKVJMuedFeU/Sa0Sy/Ia+t06Dw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-roving-focus": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.3.tgz", + "integrity": "sha512-stjCkIoMe6h+1fWtXlA6cRfikdBzCLp3SnVk7c48cv/uy3DTGoXhN76YaOYUJuy3aEDvDIKwKR5KSmvrtPvQPQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-collection": "1.0.2", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-direction": "1.0.0", + "@radix-ui/react-id": "1.0.0", + "@radix-ui/react-primitive": "1.0.2", + "@radix-ui/react-use-callback-ref": "1.0.0", "@radix-ui/react-use-controllable-state": "1.0.0" }, "peerDependencies": { @@ -11886,6 +11937,11 @@ "tailwindcss": ">=3.0.0 || insiders" } }, + "node_modules/tailwindcss-radix": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tailwindcss-radix/-/tailwindcss-radix-2.8.0.tgz", + "integrity": "sha512-1k1UfoIYgVyBl13FKwwoKavjnJ5VEaUClCTAsgz3VLquN4ay/lyaMPzkbqD71sACDs2fRGImytAUlMb4TzOt1A==" + }, "node_modules/tailwindcss/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", @@ -15035,9 +15091,9 @@ } }, "@radix-ui/react-tabs": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.0.2.tgz", - "integrity": "sha512-gOUwh+HbjCuL0UCo8kZ+kdUEG8QtpdO4sMQduJ34ZEz0r4922g9REOBM+vIsfwtGxSug4Yb1msJMJYN2Bk8TpQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.0.3.tgz", + "integrity": "sha512-4CkF/Rx1GcrusI/JZ1Rvyx4okGUs6wEenWA0RG/N+CwkRhTy7t54y7BLsWUXrAz/GRbBfHQg/Odfs/RoW0CiRA==", "requires": { "@babel/runtime": "^7.13.10", "@radix-ui/primitive": "1.0.0", @@ -15045,9 +15101,49 @@ "@radix-ui/react-direction": "1.0.0", "@radix-ui/react-id": "1.0.0", "@radix-ui/react-presence": "1.0.0", - "@radix-ui/react-primitive": "1.0.1", - "@radix-ui/react-roving-focus": "1.0.2", + "@radix-ui/react-primitive": "1.0.2", + "@radix-ui/react-roving-focus": "1.0.3", "@radix-ui/react-use-controllable-state": "1.0.0" + }, + "dependencies": { + "@radix-ui/react-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.0.2.tgz", + "integrity": "sha512-s8WdQQ6wNXpaxdZ308KSr8fEWGrg4un8i4r/w7fhiS4ElRNjk5rRcl0/C6TANG2LvLOGIxtzo/jAg6Qf73TEBw==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-primitive": "1.0.2", + "@radix-ui/react-slot": "1.0.1" + } + }, + "@radix-ui/react-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.2.tgz", + "integrity": "sha512-zY6G5Qq4R8diFPNwtyoLRZBxzu1Z+SXMlfYpChN7Dv8gvmx9X3qhDqiLWvKseKVJMuedFeU/Sa0Sy/Ia+t06Dw==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.1" + } + }, + "@radix-ui/react-roving-focus": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.0.3.tgz", + "integrity": "sha512-stjCkIoMe6h+1fWtXlA6cRfikdBzCLp3SnVk7c48cv/uy3DTGoXhN76YaOYUJuy3aEDvDIKwKR5KSmvrtPvQPQ==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-collection": "1.0.2", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-direction": "1.0.0", + "@radix-ui/react-id": "1.0.0", + "@radix-ui/react-primitive": "1.0.2", + "@radix-ui/react-use-callback-ref": "1.0.0", + "@radix-ui/react-use-controllable-state": "1.0.0" + } + } } }, "@radix-ui/react-use-callback-ref": { @@ -21553,6 +21649,11 @@ "integrity": "sha512-UU3qrOJ4lFQABY+MVADmBm+0KW3xZyhMdRvejwtXqYOL7YjHYxmuREFAZdmVG5LPe5E9CAst846SLC4j5I3dcw==", "requires": {} }, + "tailwindcss-radix": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tailwindcss-radix/-/tailwindcss-radix-2.8.0.tgz", + "integrity": "sha512-1k1UfoIYgVyBl13FKwwoKavjnJ5VEaUClCTAsgz3VLquN4ay/lyaMPzkbqD71sACDs2fRGImytAUlMb4TzOt1A==" + }, "tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", diff --git a/client/package.json b/client/package.json index 1b8fb0458f..1050739668 100644 --- a/client/package.json +++ b/client/package.json @@ -23,7 +23,7 @@ "@radix-ui/react-dialog": "^1.0.2", "@radix-ui/react-dropdown-menu": "^2.0.2", "@radix-ui/react-label": "^2.0.0", - "@radix-ui/react-tabs": "^1.0.2", + "@radix-ui/react-tabs": "^1.0.3", "@reduxjs/toolkit": "^1.9.2", "axios": "^1.3.4", "class-variance-authority": "^0.4.0", @@ -51,6 +51,7 @@ "swr": "^2.0.3", "tailwind-merge": "^1.9.1", "tailwindcss-animate": "^1.0.5", + "tailwindcss-radix": "^2.8.0", "url": "^0.11.0", "uuidv4": "^6.2.13" }, diff --git a/client/src/components/Main/BingStyles.jsx b/client/src/components/Main/BingStyles.jsx new file mode 100644 index 0000000000..bc8e45a1f3 --- /dev/null +++ b/client/src/components/Main/BingStyles.jsx @@ -0,0 +1,51 @@ +import React, { useState } from 'react'; +// import { Tabs, TabsContent, TabsList, TabsTrigger } from "../ui/Tabs"; +import { Tabs, TabsList, TabsTrigger } from '../ui/Tabs.tsx'; +import { useSelector } from 'react-redux'; +// import RowButton from './RowButton'; + +export default function BingStyles() { + const [value, setValue] = useState('fast'); + const { model } = useSelector((state) => state.submit); + + const show = model === 'bingai' || model === 'sydney'; + const defaultClasses = 'p-2 rounded-md font-normal bg-white/[.60] text-black'; + const defaultSelected = defaultClasses + 'font-medium data-[state=active]:text-white'; + + const selectedClass = (val) => val + '-tab ' + defaultSelected; + + const changeHandler = value => { + setValue(value); + }; + return ( + //
+ + + + {/* */} + {'Creative'} + + + {'Balanced'} + + + {'Precise'} + + + + //
+ ); +} diff --git a/client/src/components/Main/RowButton.jsx b/client/src/components/Main/RowButton.jsx new file mode 100644 index 0000000000..06aaa27e37 --- /dev/null +++ b/client/src/components/Main/RowButton.jsx @@ -0,0 +1,16 @@ +import React from 'react'; + +export default function RowButton({ onClick, children, text, className }) { + return ( + + ); +} \ No newline at end of file diff --git a/client/src/components/Main/TextChat.jsx b/client/src/components/Main/TextChat.jsx index 3b62132f51..a955e627ef 100644 --- a/client/src/components/Main/TextChat.jsx +++ b/client/src/components/Main/TextChat.jsx @@ -1,18 +1,17 @@ -import React, { useEffect, useRef, useState } from 'react'; +import React, { useEffect, useRef } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; import { SSE } from '~/utils/sse'; import SubmitButton from './SubmitButton'; -import Regenerate from './Regenerate'; +// import Regenerate from './Regenerate'; // not used as of Wentao's update +import BingStyles from './BingStyles'; import ModelMenu from '../Models/ModelMenu'; import Footer from './Footer'; import TextareaAutosize from 'react-textarea-autosize'; import createPayload from '~/utils/createPayload'; -import resetConvo from '~/utils/resetConvo'; import RegenerateIcon from '../svg/RegenerateIcon'; import StopGeneratingIcon from '../svg/StopGeneratingIcon'; -import { useSelector, useDispatch } from 'react-redux'; import { setConversation, - setNewConvo, setError, refreshConversation } from '~/store/convoSlice'; @@ -22,17 +21,14 @@ import { setText } from '~/store/textSlice'; import { useMessageHandler } from '../../utils/handleSubmit'; export default function TextChat({ messages }) { - const [errorMessage, setErrorMessage] = useState(''); const inputRef = useRef(null); const isComposing = useRef(false); const dispatch = useDispatch(); - const { user } = useSelector((state) => state.user); const convo = useSelector((state) => state.convo); - const { initial } = useSelector((state) => state.models); - const { isSubmitting, stopStream, submission, disabled, model, chatGptLabel, promptPrefix } = + const { isSubmitting, stopStream, submission, disabled } = useSelector((state) => state.submit); const { text } = useSelector((state) => state.text); - const { error, latestMessage } = convo; + const { latestMessage } = convo; const { ask, regenerate, stopGenerating } = useMessageHandler(); const isNotAppendable = latestMessage?.cancelled || latestMessage?.error; @@ -43,7 +39,7 @@ export default function TextChat({ messages }) { }, [convo?.conversationId]); const messageHandler = (data, currentState, currentMsg) => { - const { messages, _currentMsg, message, sender, isRegenerate } = currentState; + const { messages, message, sender, isRegenerate } = currentState; if (isRegenerate) dispatch( @@ -75,7 +71,7 @@ export default function TextChat({ messages }) { }; const cancelHandler = (data, currentState, currentMsg) => { - const { messages, _currentMsg, message, sender, isRegenerate } = currentState; + const { messages, message, sender, isRegenerate } = currentState; if (isRegenerate) dispatch( @@ -116,10 +112,9 @@ export default function TextChat({ messages }) { ); }; - const convoHandler = (data, currentState, currentMsg) => { + const convoHandler = (data, currentState) => { const { requestMessage, responseMessage } = data; - const { conversationId } = requestMessage; - const { messages, _currentMsg, message, isCustomModel, sender, isRegenerate } = + const { messages, message, isCustomModel, isRegenerate } = currentState; const { model, chatGptLabel, promptPrefix } = message; if (isRegenerate) dispatch(setMessages([...messages, responseMessage])); @@ -199,14 +194,13 @@ export default function TextChat({ messages }) { }; const errorHandler = (data, currentState, currentMsg) => { - const { initialResponse, messages, _currentMsg, message } = currentState; + const {messages, message } = currentState; console.log('Error:', data); const errorResponse = { ...data, error: true, parentMessageId: currentMsg?.messageId }; - setErrorMessage(data?.text); dispatch(setSubmitState(false)); dispatch(setMessages([...messages, currentMsg, errorResponse])); dispatch(setText(message?.text)); @@ -237,7 +231,7 @@ export default function TextChat({ messages }) { const data = JSON.parse(e.data); if (data.final) { - convoHandler(data, currentState, currentMsg); + convoHandler(data, currentState); dispatch(toggleCursor()); console.log('final', data); } @@ -268,7 +262,7 @@ export default function TextChat({ messages }) { events.onmessage = onMessage; - events.oncancel = (e) => { + events.oncancel = () => { dispatch(toggleCursor(true)); cancelHandler(latestResponseText, currentState, currentMsg); }; @@ -324,11 +318,11 @@ export default function TextChat({ messages }) { } }; - const handleCompositionStart = (e) => { + const handleCompositionStart = () => { isComposing.current = true; }; - const handleCompositionEnd = (e) => { + const handleCompositionEnd = () => { isComposing.current = false; }; @@ -341,10 +335,10 @@ export default function TextChat({ messages }) { dispatch(setText(value)); }; - const tryAgain = (e) => { - e.preventDefault(); - dispatch(setError(false)); - }; + // const tryAgain = (e) => { + // e.preventDefault(); + // dispatch(setError(false)); + // }; const isSearchView = messages?.[0]?.searchResult === true; const getPlaceholderText = () => { @@ -364,10 +358,12 @@ export default function TextChat({ messages }) { }; return ( + <>
+ {isSubmitting && !isSearchView ? (
+ ); } diff --git a/client/src/style.css b/client/src/style.css index 2f43cfe285..04f2a899db 100644 --- a/client/src/style.css +++ b/client/src/style.css @@ -28,6 +28,41 @@ transition: all 1s ease-in-out; } */ +.bing-styles { +position: absolute; +left: 0; +right: 0; +opacity: 0; +bottom: 35px; +z-index: 995; +margin-left: auto; +margin-right: auto; +width: 308px; /* Need a specific value to work */ +transition: all 0.5s ease-in-out; +pointer-events: none; +transform: translateY(-60px); +} + +.bing-styles.show { + /* bottom: -20px; */ + opacity: 1; + pointer-events: all; + transform: translateY(-20px); +} + +.creative-tab { + /* background: linear-gradient(90deg, #904887 10.79%, #8B257E 87.08%); */ + background: linear-gradient(90deg, #904887 10.79%, #8B257E 87.08%); +} + +.fast-tab { + background: linear-gradient(90deg, #2870EA 10.79%, #1B4AEF 87.08%); +} + +.precise-tab { + background: linear-gradient(90deg, #006880 10.79%, #005366 87.08%) +} + p > small { opacity: 0; animation: fadein 3s forwards; diff --git a/client/tailwind.config.js b/client/tailwind.config.js index 7c02efecf3..d4b4d637c4 100644 --- a/client/tailwind.config.js +++ b/client/tailwind.config.js @@ -45,6 +45,7 @@ module.exports = { }, plugins: [ require('tailwindcss-animate'), + require("tailwindcss-radix")(), // require('@tailwindcss/typography'), ] }; From 89ab74a913d4f0c158bc141cb660f4af3b917ea6 Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Fri, 24 Mar 2023 16:21:10 -0400 Subject: [PATCH 2/6] feat: complete frontend/backend tone handling --- api/app/clients/sydney.js | 4 + api/models/schema/convoSchema.js | 4 + .../components/Conversations/Conversation.jsx | 13 +- client/src/components/Conversations/index.jsx | 3 +- client/src/components/Main/BingStyles.jsx | 23 +-- client/src/store/convoSlice.js | 2 + client/src/utils/createPayload.js | 9 +- client/src/utils/handleSubmit.js | 135 +++++++++--------- 8 files changed, 105 insertions(+), 88 deletions(-) diff --git a/api/app/clients/sydney.js b/api/app/clients/sydney.js index 3466f71c17..beaa6f4029 100644 --- a/api/app/clients/sydney.js +++ b/api/app/clients/sydney.js @@ -22,6 +22,10 @@ const askSydney = async ({ text, onProgress, convo }) => { options = { ...options, jailbreakConversationId: convo.jailbreakConversationId, parentMessageId: convo.parentMessageId }; } + if (convo.toneStyle) { + options.toneStyle = convo.toneStyle; + } + console.log('sydney options', options); const res = await sydneyClient.sendMessage(text, options diff --git a/api/models/schema/convoSchema.js b/api/models/schema/convoSchema.js index a654b1425a..79e621ef8e 100644 --- a/api/models/schema/convoSchema.js +++ b/api/models/schema/convoSchema.js @@ -32,6 +32,10 @@ const convoSchema = mongoose.Schema( invocationId: { type: String }, + toneStyle: { + type: String, + default: null + }, chatGptLabel: { type: String, default: null diff --git a/client/src/components/Conversations/Conversation.jsx b/client/src/components/Conversations/Conversation.jsx index 5d503372fd..c0ae103d33 100644 --- a/client/src/components/Conversations/Conversation.jsx +++ b/client/src/components/Conversations/Conversation.jsx @@ -23,7 +23,6 @@ export default function Conversation({ }) { const [renaming, setRenaming] = useState(false); const [titleInput, setTitleInput] = useState(title); - const { modelMap } = useSelector((state) => state.models); const { stopStream } = useSelector((state) => state.submit); const inputRef = useRef(null); const dispatch = useDispatch(); @@ -49,7 +48,8 @@ export default function Conversation({ conversationSignature, jailbreakConversationId, clientId, - invocationId + invocationId, + toneStyle, } = bingData; dispatch( setConversation({ @@ -59,6 +59,7 @@ export default function Conversation({ conversationSignature, clientId, invocationId, + toneStyle, latestMessage: null }) ); @@ -71,6 +72,7 @@ export default function Conversation({ conversationSignature: null, clientId: null, invocationId: null, + toneStyle: null, latestMessage: null }) ); @@ -85,13 +87,6 @@ export default function Conversation({ dispatch(setCustomModel(null)); } - // if (modelMap[chatGptLabel.toLowerCase()]) { - // console.log('custom model', chatGptLabel); - // dispatch(setCustomModel(chatGptLabel.toLowerCase())); - // } else { - // dispatch(setCustomModel(null)); - // } - dispatch(setMessages(data)); dispatch(setCustomGpt(convo)); dispatch(setText('')); diff --git a/client/src/components/Conversations/index.jsx b/client/src/components/Conversations/index.jsx index eaa59b0097..aaddaaba86 100644 --- a/client/src/components/Conversations/index.jsx +++ b/client/src/components/Conversations/index.jsx @@ -14,7 +14,8 @@ export default function Conversations({ conversations, conversationId, moveToTop conversationSignature: convo.conversationSignature, parentMessageId: convo.parentMessageId || null, clientId: convo.clientId, - invocationId: convo.invocationId + invocationId: convo.invocationId, + toneStyle: convo.toneStyle, } : null; diff --git a/client/src/components/Main/BingStyles.jsx b/client/src/components/Main/BingStyles.jsx index bc8e45a1f3..b06021fd3e 100644 --- a/client/src/components/Main/BingStyles.jsx +++ b/client/src/components/Main/BingStyles.jsx @@ -1,14 +1,23 @@ -import React, { useState } from 'react'; -// import { Tabs, TabsContent, TabsList, TabsTrigger } from "../ui/Tabs"; +import React, { useState, useEffect } from 'react'; import { Tabs, TabsList, TabsTrigger } from '../ui/Tabs.tsx'; -import { useSelector } from 'react-redux'; -// import RowButton from './RowButton'; +import { useDispatch, useSelector } from 'react-redux'; +import { setConversation } from '~/store/convoSlice'; export default function BingStyles() { + const dispatch = useDispatch(); const [value, setValue] = useState('fast'); const { model } = useSelector((state) => state.submit); + const { conversationId } = useSelector((state) => state.convo); + const { messages } = useSelector((state) => state.messages); + const isBing = model === 'bingai' || model === 'sydney'; - const show = model === 'bingai' || model === 'sydney'; + useEffect(() => { + if (isBing && !conversationId) { + dispatch(setConversation({ toneStyle: value })); + } + }, [isBing, conversationId, model, value, dispatch]); + + const show = isBing && (!conversationId || messages?.length === 0); const defaultClasses = 'p-2 rounded-md font-normal bg-white/[.60] text-black'; const defaultSelected = defaultClasses + 'font-medium data-[state=active]:text-white'; @@ -16,9 +25,9 @@ export default function BingStyles() { const changeHandler = value => { setValue(value); + dispatch(setConversation({ toneStyle: value })); }; return ( - //
- {/* */} {'Creative'} - //
); } diff --git a/client/src/store/convoSlice.js b/client/src/store/convoSlice.js index e8da18bb3b..d800535296 100644 --- a/client/src/store/convoSlice.js +++ b/client/src/store/convoSlice.js @@ -9,6 +9,7 @@ const initialState = { conversationSignature: null, clientId: null, invocationId: null, + toneStyle: null, chatGptLabel: null, promptPrefix: null, convosLoading: false, @@ -58,6 +59,7 @@ const currentSlice = createSlice({ state.conversationSignature = null; state.clientId = null; state.invocationId = null; + state.toneStyle = null; state.chatGptLabel = null; state.promptPrefix = null; state.convosLoading = false; diff --git a/client/src/utils/createPayload.js b/client/src/utils/createPayload.js index fd195e43e1..a1b0ff67bb 100644 --- a/client/src/utils/createPayload.js +++ b/client/src/utils/createPayload.js @@ -13,6 +13,10 @@ export default function createPayload({ convo, message }) { } const isBing = model === 'bingai' || model === 'sydney'; + if (isBing && !convo?.conversationId) { + payload.toneStyle = convo.toneStyle || 'fast'; + } + if (isBing && convo?.conversationId) { payload = { ...payload, @@ -20,7 +24,8 @@ export default function createPayload({ convo, message }) { conversationId: convo.conversationId, conversationSignature: convo.conversationSignature, clientId: convo.clientId, - invocationId: convo.invocationId + invocationId: convo.invocationId, + toneStyle: convo.toneStyle, }; } @@ -28,4 +33,4 @@ export default function createPayload({ convo, message }) { server = model === 'bingai' ? server + '/bing' : server; server = model === 'sydney' ? server + '/sydney' : server; return { server, payload }; -}; +} diff --git a/client/src/utils/handleSubmit.js b/client/src/utils/handleSubmit.js index 897e94d6c4..11a5484474 100644 --- a/client/src/utils/handleSubmit.js +++ b/client/src/utils/handleSubmit.js @@ -1,4 +1,3 @@ -import { SSE } from './sse'; import resetConvo from './resetConvo'; import { useSelector, useDispatch } from 'react-redux'; import { setNewConvo } from '~/store/convoSlice'; @@ -14,7 +13,6 @@ const useMessageHandler = () => { const { initial } = useSelector((state) => state.models); const { messages } = useSelector((state) => state.messages); const { model, chatGptLabel, promptPrefix, isSubmitting } = useSelector((state) => state.submit); - const { text } = useSelector((state) => state.text); const { latestMessage, error } = convo; const ask = ({ text, parentMessageId=null, conversationId=null, messageId=null}, { isRegenerate=false }={}) => { @@ -76,7 +74,7 @@ const useMessageHandler = () => { if (parentMessage && parentMessage.isCreatedByUser) ask({ ...parentMessage }, { isRegenerate: true }) else - console.error('Failed to regenerate the message: parentMessage not found or not created by user.', message); + console.error('Failed to regenerate the message: parentMessage not found or not created by user.'); } const stopGenerating = () => { @@ -88,78 +86,79 @@ const useMessageHandler = () => { export { useMessageHandler }; -export default function handleSubmit({ - model, - text, - convo, - messageHandler, - convoHandler, - errorHandler, - chatGptLabel, - promptPrefix -}) { - const endpoint = `/api/ask`; - let payload = { model, text, chatGptLabel, promptPrefix }; - if (convo.conversationId && convo.parentMessageId) { - payload = { - ...payload, - conversationId: convo.conversationId, - parentMessageId: convo.parentMessageId - }; - } +// deprecated +// export default function handleSubmit({ +// model, +// text, +// convo, +// messageHandler, +// convoHandler, +// errorHandler, +// chatGptLabel, +// promptPrefix +// }) { +// const endpoint = `/api/ask`; +// let payload = { model, text, chatGptLabel, promptPrefix }; +// if (convo.conversationId && convo.parentMessageId) { +// payload = { +// ...payload, +// conversationId: convo.conversationId, +// parentMessageId: convo.parentMessageId +// }; +// } - const isBing = model === 'bingai' || model === 'sydney'; - if (isBing && convo.conversationId) { +// const isBing = model === 'bingai' || model === 'sydney'; +// if (isBing && convo.conversationId) { - payload = { - ...payload, - jailbreakConversationId: convo.jailbreakConversationId, - conversationId: convo.conversationId, - conversationSignature: convo.conversationSignature, - clientId: convo.clientId, - invocationId: convo.invocationId, - }; - } +// payload = { +// ...payload, +// jailbreakConversationId: convo.jailbreakConversationId, +// conversationId: convo.conversationId, +// conversationSignature: convo.conversationSignature, +// clientId: convo.clientId, +// invocationId: convo.invocationId, +// }; +// } - let server = endpoint; - server = model === 'bingai' ? server + '/bing' : server; - server = model === 'sydney' ? server + '/sydney' : server; +// let server = endpoint; +// server = model === 'bingai' ? server + '/bing' : server; +// server = model === 'sydney' ? server + '/sydney' : server; - const events = new SSE(server, { - payload: JSON.stringify(payload), - headers: { 'Content-Type': 'application/json' } - }); +// const events = new SSE(server, { +// payload: JSON.stringify(payload), +// headers: { 'Content-Type': 'application/json' } +// }); - events.onopen = function () { - console.log('connection is opened'); - }; +// events.onopen = function () { +// console.log('connection is opened'); +// }; - events.onmessage = function (e) { - const data = JSON.parse(e.data); - let text = data.text || data.response; - if (data.message) { - messageHandler(text, events); - } +// events.onmessage = function (e) { +// const data = JSON.parse(e.data); +// let text = data.text || data.response; +// if (data.message) { +// messageHandler(text, events); +// } - if (data.final) { - convoHandler(data); - console.log('final', data); - } else { - // console.log('dataStream', data); - } - }; +// if (data.final) { +// convoHandler(data); +// console.log('final', data); +// } else { +// // console.log('dataStream', data); +// } +// }; - events.onerror = function (e) { - console.log('error in opening conn.'); - events.close(); - errorHandler(e); - }; +// events.onerror = function (e) { +// console.log('error in opening conn.'); +// events.close(); +// errorHandler(e); +// }; - events.addEventListener('stop', () => { - // Close the SSE stream - console.log('stop event received'); - events.close(); - }); +// events.addEventListener('stop', () => { +// // Close the SSE stream +// console.log('stop event received'); +// events.close(); +// }); - events.stream(); -} +// events.stream(); +// } From a6c93ad681ca07ddc189a22e85432361dabe279d Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Fri, 24 Mar 2023 16:31:27 -0400 Subject: [PATCH 3/6] dark mode in progress --- client/src/components/Main/BingStyles.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/components/Main/BingStyles.jsx b/client/src/components/Main/BingStyles.jsx index b06021fd3e..512b8d0926 100644 --- a/client/src/components/Main/BingStyles.jsx +++ b/client/src/components/Main/BingStyles.jsx @@ -18,7 +18,7 @@ export default function BingStyles() { }, [isBing, conversationId, model, value, dispatch]); const show = isBing && (!conversationId || messages?.length === 0); - const defaultClasses = 'p-2 rounded-md font-normal bg-white/[.60] text-black'; + const defaultClasses = 'p-2 rounded-md font-normal bg-white/[.60] dark:bg-gray-700 text-black'; const defaultSelected = defaultClasses + 'font-medium data-[state=active]:text-white'; const selectedClass = (val) => val + '-tab ' + defaultSelected; @@ -33,7 +33,7 @@ export default function BingStyles() { className={`shadow-md mb-1 bing-styles ${show ? 'show' : ''}`} onValueChange={changeHandler} > - + Date: Fri, 24 Mar 2023 19:02:42 -0400 Subject: [PATCH 4/6] feat: dark mode for style tabs --- client/src/components/ui/Tabs.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/components/ui/Tabs.tsx b/client/src/components/ui/Tabs.tsx index fc0087daf5..93856461d3 100644 --- a/client/src/components/ui/Tabs.tsx +++ b/client/src/components/ui/Tabs.tsx @@ -14,7 +14,7 @@ const TabsList = React.forwardRef< (({ className, ...props }, ref) => ( (({ className, ...props }, ref) => ( Date: Sat, 25 Mar 2023 09:34:00 -0400 Subject: [PATCH 5/6] feat: complete bing styles (view) --- client/src/components/Main/BingStyles.jsx | 9 +- client/src/components/Main/TextChat.jsx | 169 ++++++++++-------- .../Messages/Content/TextWrapper.jsx | 4 +- client/src/style.css | 2 +- 4 files changed, 102 insertions(+), 82 deletions(-) diff --git a/client/src/components/Main/BingStyles.jsx b/client/src/components/Main/BingStyles.jsx index 512b8d0926..a54134e34d 100644 --- a/client/src/components/Main/BingStyles.jsx +++ b/client/src/components/Main/BingStyles.jsx @@ -1,16 +1,16 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, forwardRef } from 'react'; import { Tabs, TabsList, TabsTrigger } from '../ui/Tabs.tsx'; import { useDispatch, useSelector } from 'react-redux'; import { setConversation } from '~/store/convoSlice'; -export default function BingStyles() { +function BingStyles(props, ref) { const dispatch = useDispatch(); const [value, setValue] = useState('fast'); const { model } = useSelector((state) => state.submit); const { conversationId } = useSelector((state) => state.convo); const { messages } = useSelector((state) => state.messages); + const isBing = model === 'bingai' || model === 'sydney'; - useEffect(() => { if (isBing && !conversationId) { dispatch(setConversation({ toneStyle: value })); @@ -32,6 +32,7 @@ export default function BingStyles() { defaultValue={value} className={`shadow-md mb-1 bing-styles ${show ? 'show' : ''}`} onValueChange={changeHandler} + ref={ref} > ); } + +export default forwardRef(BingStyles); diff --git a/client/src/components/Main/TextChat.jsx b/client/src/components/Main/TextChat.jsx index a955e627ef..c2c37796ac 100644 --- a/client/src/components/Main/TextChat.jsx +++ b/client/src/components/Main/TextChat.jsx @@ -10,11 +10,7 @@ import TextareaAutosize from 'react-textarea-autosize'; import createPayload from '~/utils/createPayload'; import RegenerateIcon from '../svg/RegenerateIcon'; import StopGeneratingIcon from '../svg/StopGeneratingIcon'; -import { - setConversation, - setError, - refreshConversation -} from '~/store/convoSlice'; +import { setConversation, setError, refreshConversation } from '~/store/convoSlice'; import { setMessages } from '~/store/messageSlice'; import { setSubmitState, toggleCursor } from '~/store/submitSlice'; import { setText } from '~/store/textSlice'; @@ -22,12 +18,12 @@ import { useMessageHandler } from '../../utils/handleSubmit'; export default function TextChat({ messages }) { const inputRef = useRef(null); + const bingStylesRef = useRef(null); const isComposing = useRef(false); const dispatch = useDispatch(); - const convo = useSelector((state) => state.convo); - const { isSubmitting, stopStream, submission, disabled } = - useSelector((state) => state.submit); - const { text } = useSelector((state) => state.text); + const convo = useSelector(state => state.convo); + const { isSubmitting, stopStream, submission, disabled } = useSelector(state => state.submit); + const { text } = useSelector(state => state.text); const { latestMessage } = convo; const { ask, regenerate, stopGenerating } = useMessageHandler(); @@ -38,6 +34,22 @@ export default function TextChat({ messages }) { inputRef.current?.focus(); }, [convo?.conversationId]); + // controls the height of Bing tone style tabs + useEffect(() => { + if (!inputRef.current) { + return; // wait for the ref to be available + } + + const resizeObserver = new ResizeObserver(() => { + const newHeight = inputRef.current.clientHeight; + if (newHeight >= 24) { // 24 is the default height of the input + bingStylesRef.current.style.bottom = 15 + newHeight + 'px'; + } + }); + resizeObserver.observe(inputRef.current); + return () => resizeObserver.disconnect(); + }, [inputRef]); + const messageHandler = (data, currentState, currentMsg) => { const { messages, message, sender, isRegenerate } = currentState; @@ -114,8 +126,7 @@ export default function TextChat({ messages }) { const convoHandler = (data, currentState) => { const { requestMessage, responseMessage } = data; - const { messages, message, isCustomModel, isRegenerate } = - currentState; + const { messages, message, isCustomModel, isRegenerate } = currentState; const { model, chatGptLabel, promptPrefix } = message; if (isRegenerate) dispatch(setMessages([...messages, responseMessage])); else dispatch(setMessages([...messages, requestMessage, responseMessage])); @@ -194,7 +205,7 @@ export default function TextChat({ messages }) { }; const errorHandler = (data, currentState, currentMsg) => { - const {messages, message } = currentState; + const { messages, message } = currentState; console.log('Error:', data); const errorResponse = { ...data, @@ -223,7 +234,7 @@ export default function TextChat({ messages }) { let latestResponseText = ''; const { server, payload } = createPayload(submission); - const onMessage = (e) => { + const onMessage = e => { if (stopStream) { return; } @@ -298,7 +309,7 @@ export default function TextChat({ messages }) { stopGenerating(); }; - const handleKeyDown = (e) => { + const handleKeyDown = e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); } @@ -308,7 +319,11 @@ export default function TextChat({ messages }) { } }; - const handleKeyUp = (e) => { + const handleKeyUp = e => { + if (e.keyCode === 8 && e.target.value.trim() === '') { + dispatch(setText(e.target.value)); + } + if (e.key === 'Enter' && e.shiftKey) { return console.log('Enter + Shift'); } @@ -326,7 +341,7 @@ export default function TextChat({ messages }) { isComposing.current = false; }; - const changeHandler = (e) => { + const changeHandler = e => { const { value } = e.target; // if (isSubmitting && (value === '' || value === '\n')) { @@ -343,80 +358,80 @@ export default function TextChat({ messages }) { const isSearchView = messages?.[0]?.searchResult === true; const getPlaceholderText = () => { if (isSearchView) { - return 'Click a message title to open its conversation.' + return 'Click a message title to open its conversation.'; } if (disabled) { return 'Choose another model or customize GPT again'; } - + if (isNotAppendable) { - return 'Edit your message or Regenerate.' + return 'Edit your message or Regenerate.'; } - + return ''; }; return ( <> -
- -
- - - {isSubmitting && !isSearchView ? ( - - ) : latestMessage && !latestMessage?.isCreatedByUser && !isSearchView ? ( - - ) : null} - -
- - - +
+ +
+ + + {isSubmitting && !isSearchView ? ( + + ) : latestMessage && !latestMessage?.isCreatedByUser && !isSearchView ? ( + + ) : null} + +
+ + + +
-
- -
-
+ +
+
); } diff --git a/client/src/components/Messages/Content/TextWrapper.jsx b/client/src/components/Messages/Content/TextWrapper.jsx index 3cfd0a1b37..b8a242cf1e 100644 --- a/client/src/components/Messages/Content/TextWrapper.jsx +++ b/client/src/components/Messages/Content/TextWrapper.jsx @@ -46,7 +46,7 @@ const inLineWrap = (parts) => { }); }; -export default function TextWrapper({ text, generateCursor }) { +function TextWrapper({ text, generateCursor }) { let embedTest = false; let result = null; @@ -158,3 +158,5 @@ export default function TextWrapper({ text, generateCursor }) { ); } + +export default React.memo(TextWrapper); \ No newline at end of file diff --git a/client/src/style.css b/client/src/style.css index 04f2a899db..01d837a863 100644 --- a/client/src/style.css +++ b/client/src/style.css @@ -33,7 +33,7 @@ position: absolute; left: 0; right: 0; opacity: 0; -bottom: 35px; +bottom: 39px; z-index: 995; margin-left: auto; margin-right: auto; From 26e7a715e0cf1e81edd8e1e7f9925e1b93a3d79c Mon Sep 17 00:00:00 2001 From: Daniel Avila Date: Sat, 25 Mar 2023 09:40:36 -0400 Subject: [PATCH 6/6] feat: complete bing styles (bing is passed tone style) --- api/app/clients/bingai.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/api/app/clients/bingai.js b/api/app/clients/bingai.js index dcf150d1cf..0ed57172b9 100644 --- a/api/app/clients/bingai.js +++ b/api/app/clients/bingai.js @@ -2,7 +2,7 @@ require('dotenv').config(); const { KeyvFile } = require('keyv-file'); const askBing = async ({ text, onProgress, convo }) => { - const { BingAIClient } = (await import('@waylaidwanderer/chatgpt-api')); + const { BingAIClient } = await import('@waylaidwanderer/chatgpt-api'); const bingAIClient = new BingAIClient({ // "_U" cookie from bing.com @@ -11,7 +11,7 @@ const askBing = async ({ text, onProgress, convo }) => { // cookies: '', debug: false, cache: { store: new KeyvFile({ filename: './data/cache.json' }) }, - proxy: process.env.PROXY || null, + proxy: process.env.PROXY || null }); let options = { onProgress }; @@ -19,8 +19,15 @@ const askBing = async ({ text, onProgress, convo }) => { options = { ...options, ...convo }; } - if (options?.jailbreakConversationId == 'false') - options.jailbreakConversationId = false + if (options?.jailbreakConversationId == 'false') { + options.jailbreakConversationId = false; + } + + if (convo.toneStyle) { + options.toneStyle = convo.toneStyle; + } + + console.log('bing options', options); const res = await bingAIClient.sendMessage(text, options);