feat(bing-settings): Work in Progress, will finish tomorrow

feat(api): add @dqbd/tiktoken package as a dependency
feat(api): add /api/tokenizer endpoint to tokenize text using @dqbd/tiktoken
feat(client): add toneStyle dropdown to BingAI Settings component
feat(client): add token count to BingAI Settings component

style(ui): add z-index to Dropdown and EndpointOptionsPopover components

Add z-index to Dropdown and EndpointOptionsPopover components to ensure they are displayed above other components.
This commit is contained in:
Daniel Avila 2023-04-03 21:18:19 -04:00
parent 03f63975cc
commit 89e38d67f4
8 changed files with 78 additions and 16 deletions

3
api/package-lock.json generated
View file

@ -6,9 +6,10 @@
"packages": {
"": {
"name": "chatgpt-clone",
"version": "0.2.0",
"version": "0.3.0",
"license": "ISC",
"dependencies": {
"@dqbd/tiktoken": "^1.0.2",
"@keyv/mongo": "^2.1.8",
"@waylaidwanderer/chatgpt-api": "^1.33.2",
"axios": "^1.3.4",

View file

@ -19,6 +19,7 @@
},
"homepage": "https://github.com/danny-avila/chatgpt-clone#readme",
"dependencies": {
"@dqbd/tiktoken": "^1.0.2",
"@keyv/mongo": "^2.1.8",
"@waylaidwanderer/chatgpt-api": "^1.33.2",
"axios": "^1.3.4",

View file

@ -59,6 +59,7 @@ const projectPath = path.join(__dirname, '..', '..', 'client');
app.use('/api/customGpts', routes.authenticatedOr401, routes.customGpts);
app.use('/api/presets', routes.authenticatedOr401, routes.presets);
app.use('/api/prompts', routes.authenticatedOr401, routes.prompts);
app.use('/api/tokenizer', routes.authenticatedOr401, routes.tokenizer);
app.use('/auth', routes.auth);
app.get('/api/endpoints', function (req, res) {

View file

@ -5,6 +5,7 @@ const presets = require('./presets');
const customGpts = require('./customGpts');
const prompts = require('./prompts');
const search = require('./search');
const tokenizer = require('./tokenizer');
const { router: auth, authenticatedOr401, authenticatedOrRedirect } = require('./auth');
module.exports = {
@ -16,6 +17,7 @@ module.exports = {
customGpts,
prompts,
auth,
tokenizer,
authenticatedOr401,
authenticatedOrRedirect
};

View file

@ -0,0 +1,33 @@
const express = require('express');
const router = express.Router();
const { Tiktoken } = require("@dqbd/tiktoken/lite");
const { load } = require("@dqbd/tiktoken/load");
const registry = require("@dqbd/tiktoken/registry.json");
const models = require("@dqbd/tiktoken/model_to_encoding.json");
router.post('/', async (req, res) => {
console.log('hit');
const input = req.body;
console.log(typeof req.body === 'object' ? { ...req.body, ...req.query } : req.query);
const model = await load(registry[models["gpt-3.5-turbo"]]);
const encoder = new Tiktoken(
model.bpe_ranks,
model.special_tokens,
model.pat_str
);
// work in progress
const tokens = encoder.encode('dsfsdf sdf sdfsdf sdf sdf sdf sdf ');
res.status(201).send({
tokens,
count: tokens.length
});
encoder.free();
});
module.exports = router;

View file

@ -1,8 +1,9 @@
import React from 'react';
import React, { useState } from 'react';
import TextareaAutosize from 'react-textarea-autosize';
import { Input } from '~/components/ui/Input.tsx';
import { Label } from '~/components/ui/Label.tsx';
import { Checkbox } from '~/components/ui/Checkbox.tsx';
import Dropdown from '~/components/ui/Dropdown';
import { cn } from '~/utils/';
// import ModelDropDown from '../../ui/ModelDropDown';
// import { Slider } from '~/components/ui/Slider.tsx';
@ -15,15 +16,30 @@ const optionText =
'p-0 shadow-none text-right pr-1 h-8 border-transparent focus:ring-[#10a37f] focus:ring-offset-0 focus:ring-opacity-100 hover:bg-gray-800/10 dark:hover:bg-white/10 focus:bg-gray-800/10 dark:focus:bg-white/10 transition-colors';
function Settings(props) {
// const [showSystemMessage, setShowSystemMessage] = React.useState(false);
const { readonly, context, setContext, systemMessage, setSystemMessage, jailbreak, setJailbreak } = props;
const { readonly, context, systemMessage, jailbreak, toneStyle, setOption } = props;
const showSystemMessage = jailbreak;
const setContext = setOption('context');
const setSystemMessage = setOption('systemMessage');
const setJailbreak = setOption('jailbreak');
// console.log('data', data);
return (
<>
<div className="grid gap-6 sm:grid-cols-2">
<div className="col-span-1 flex flex-col items-center justify-start gap-6">
<div className="grid w-full items-center gap-2">
<Dropdown
id="toneStyle-dropdown"
value={toneStyle}
onChange={setOption('toneStyle')}
options={['creative', 'fast', 'balanced', 'precise']}
className={cn(
defaultTextProps,
'flex h-10 max-h-10 w-full resize-none focus:outline-none focus:ring-0 focus:ring-opacity-0 focus:ring-offset-0'
)}
containerClassName="flex w-full resize-none"
/>
<Label
htmlFor="context"
className="text-left text-sm font-medium"
@ -35,12 +51,13 @@ function Settings(props) {
disabled={readonly}
value={context || ''}
onChange={e => setContext(e.target.value || null)}
placeholder="Set custom instructions. Defaults to: 'You are ChatGPT, a large language model trained by OpenAI.'"
placeholder="Bing can use up to 7k tokens for 'context', text that it can reference per 1 conversation. The specific limit is not known but may run into errors exceeding 7k tokens"
className={cn(
defaultTextProps,
'flex max-h-[300px] min-h-[100px] w-full resize-none px-3 py-2 '
'flex max-h-[300px] min-h-[100px] w-full resize-none px-3 py-2'
)}
/>
<small className='mb-5'>{'Token count: 1200 (work in progress)'}</small>
</div>
</div>
<div className="col-span-1 flex flex-col items-center justify-start gap-6">
@ -50,7 +67,7 @@ function Settings(props) {
id="jailbreak"
disabled={readonly}
checked={jailbreak}
className="dark:border-gray-500 dark:bg-gray-700 dark:text-gray-50 focus:ring-opacity-20 dark:focus:ring-opacity-50 dark:focus:ring-offset-0 dark:focus:ring-gray-600"
className="focus:ring-opacity-20 dark:border-gray-500 dark:bg-gray-700 dark:text-gray-50 dark:focus:ring-gray-600 dark:focus:ring-opacity-50 dark:focus:ring-offset-0"
// onCheckedChange={setJailbreak}
onCheckedChange={checked => {
setJailbreak(checked);
@ -65,10 +82,17 @@ function Settings(props) {
</label>
<Label
htmlFor="systemMessage"
className="text-right text-sm font-medium mr-0 w-full"
className="mr-0 w-full text-right text-sm font-medium"
style={{ opacity: showSystemMessage ? '1' : '0' }}
>
System Message <small className="opacity-40">(default: Sydney)</small>
<a
href="https://github.com/danny-avila/chatgpt-clone/blob/main/client/defaultSystemMessage.md"
target="_blank"
className="text-blue-500 transition-colors duration-200 hover:text-blue-800 dark:text-blue-400 dark:hover:text-blue-500"
>
System Message
</a>{' '}
<small className="opacity-40">(default: Sydney)</small>
</Label>
</div>
{showSystemMessage && (
@ -84,10 +108,10 @@ function Settings(props) {
disabled={readonly}
value={systemMessage || ''}
onChange={e => setSystemMessage(e.target.value || null)}
placeholder="Set custom instructions. Defaults to: 'You are ChatGPT, a large language model trained by OpenAI.'"
placeholder="WARNING: Misuse of this feature can get you BANNED from using Bing! Click on 'System Message' for full instructions and the default message if omitted, which is the 'Sydney' preset that is considered safe."
className={cn(
defaultTextProps,
'flex max-h-[300px] min-h-[100px] w-full resize-none px-3 py-2 '
'flex max-h-[300px] min-h-[148px] w-full resize-none px-3 py-2 '
)}
/>
</>

View file

@ -114,13 +114,13 @@ function BingAIOptions() {
</div>
<EndpointOptionsPopover
content={
<div className="px-4 py-4">
<div className="px-4 py-4 z-50">
<Settings
context={context}
systemMessage={systemMessage}
setContext={setOption('context')}
setSystemMessage={setOption('systemMessage')}
setJailbreak={setOption('jailbreak')}
jailbreak={jailbreak}
toneStyle={toneStyle}
setOption={setOption}
/>
</div>
}

View file

@ -39,7 +39,7 @@ function Dropdown({ value, onChange, options, className, containerClassName }) {
</svg>
</span>
</Listbox.Button>
<Listbox.Options className="absolute z-10 mt-2 max-h-60 w-full overflow-auto rounded bg-white text-base text-xs ring-1 ring-black/10 focus:outline-none dark:bg-gray-800 dark:ring-white/20 dark:last:border-0 md:w-[100%]">
<Listbox.Options className="absolute z-50 mt-2 max-h-60 w-full overflow-auto rounded bg-white text-base text-xs ring-1 ring-black/10 focus:outline-none dark:bg-gray-800 dark:ring-white/20 dark:last:border-0 md:w-[100%] ">
{options.map((item, i) => (
<Listbox.Option
key={i}