Feat: PaLM 2 (#262)

* feat(api): add googleapis package to package.json
feat(api): add reqDemo.js file to make a request to Google Cloud AI Platform API to get a response from a chatbot model.

* feat: add PaLM2 support

* feat(conversationPreset.js): add support for topP and topK for google endpoint
feat(askGoogle.js): add support for topP and topK for google endpoint
feat(ask/index.js): add google endpoint
feat(endpoints.js): add google endpoint
feat(MessageHeader.jsx): add support for modelLabel for google endpoint
feat(PresetItem.jsx): add support for modelLabel for google endpoint
feat(HoverButtons.jsx): add support for google endpoint
feat(createPayload.ts): add google endpoint
feat(types.ts): add google endpoint
feat(store/endpoints.js): add google endpoint
feat(cleanupPreset.js): add support for topP and topK for google endpoint
feat(getDefaultConversation.js): add support for topP and topK for google endpoint
feat(handleSubmit.js): add support for topP and topK for google endpoint

* fix: messages payload

* refactor(GoogleClient.js): set maxContextTokens based on isTextModel value
feat(GoogleClient.js): add delay option to TextStream constructor
feat(getIcon.jsx): add support for google endpoint and PaLM2 model label

* feat: palm frontend changes

* feat(askGoogle.js): set default example to empty input and output
feat(Examples.jsx): add ability to add and remove examples
refactor(Settings.jsx): remove examples from props and setOption function

style(GoogleOptions): remove unnecessary whitespace after Settings2 import
feat(GoogleOptions): add addExample and removeExample functions to manage examples
fix(cleanupPreset): set default example to [{ input: '', output: ''}]
fix(getDefaultConversation): set default example to [{ input: '', output: ''}]
fix(handleSubmit): set default example to [{ input: '', output: ''}]

* style(client): adjust height of settings and examples components to 350px
fix(client): fix path to palm.png image in getIcon.jsx file

* style(EndpointOptionsPopover.jsx, Examples.jsx, Settings.jsx): improve button styles and update input placeholders

* feat (palm): finalize examples on the frontend

* feat(GoogleClient.js): filter out empty examples in options
feat(GoogleClient.js): add support for promptPrefix in buildPayload method
feat(GoogleClient.js): add support for examples in buildPayload method
feat(conversationPreset.js): add maxOutputTokens field to conversation preset schema
feat(presetSchema.js): add examples field to preset schema
feat(askGoogle.js): add support for examples and promptPrefix in endpointOption
feat(EditPresetDialog.jsx): add Examples component for Google endpoint
feat(EditPresetDialog.jsx): add button to show/hide Examples component
feat(EditPresetDialog.jsx): add functionality to add, remove, and edit examples in Examples component
feat(EndpointOptionsDialog.jsx): change endpoint name to PaLM for Google endpoint
feat(Settings.jsx): add maxHeight prop to limit height of Settings component in EditPresetDialog and EndpointOptionsDialog

fix(Settings.jsx): add examples prop to ChatGPTBrowser component
fix(EndpointItem.jsx): add alternate name for google endpoint
fix(MessageHeader.jsx): change title for google endpoint to PaLM
feat(endpoints.js): add google endpoint to endpointsConfig
fix(cleanupPreset.js): add missing comma in examples array

* chore: change endpoint order

* feat(PaLM 2): complete for testing

* fix(PaLM): handle blocked messages
This commit is contained in:
Danny Avila 2023-05-13 16:29:06 -04:00 committed by GitHub
parent 95c97561ae
commit 3414690e42
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 2369 additions and 79 deletions

View file

@ -40,7 +40,7 @@ function Settings(props) {
return (
<>
<div className="max-h-[350px] overflow-y-auto">
<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">
@ -141,7 +141,7 @@ function Settings(props) {
)}
</div>
</div>
</>
</div>
);
}

View file

@ -1,4 +1,6 @@
import React, { useEffect, useState } from 'react';
import Examples from './Google/Examples.jsx';
import MessagesSquared from '~/components/svg/MessagesSquared.jsx';
import { useSetRecoilState, useRecoilValue } from 'recoil';
import filenamify from 'filenamify';
import axios from 'axios';
@ -7,6 +9,7 @@ import DialogTemplate from '../ui/DialogTemplate';
import { Dialog, DialogClose, DialogButton } from '../ui/Dialog.tsx';
import { Input } from '../ui/Input.tsx';
import { Label } from '../ui/Label.tsx';
import { Button } from '../ui/Button.tsx';
import Dropdown from '../ui/Dropdown';
import { cn } from '~/utils/';
import cleanupPreset from '~/utils/cleanupPreset';
@ -18,11 +21,14 @@ import store from '~/store';
const EditPresetDialog = ({ open, onOpenChange, preset: _preset, title }) => {
// const [title, setTitle] = useState('My Preset');
const [preset, setPreset] = useState(_preset);
const [showExamples, setShowExamples] = useState(false);
const setPresets = useSetRecoilState(store.presets);
const availableEndpoints = useRecoilValue(store.availableEndpoints);
const endpointsConfig = useRecoilValue(store.endpointsConfig);
const triggerExamples = () => setShowExamples(prev => !prev);
const setOption = param => newValue => {
let update = {};
update[param] = newValue;
@ -37,6 +43,69 @@ const EditPresetDialog = ({ open, onOpenChange, preset: _preset, title }) => {
);
};
const setExample = (i, type, newValue = null) => {
let update = {};
let current = preset?.examples.slice() || [];
let currentExample = { ...current[i] } || {};
currentExample[type] = { content: newValue };
current[i] = currentExample;
update.examples = current;
setPreset(prevState =>
cleanupPreset({
preset: {
...prevState,
...update
},
endpointsConfig
})
);
};
const addExample = () => {
let update = {};
let current = preset?.examples.slice() || [];
current.push({ input: { content: '' }, output: { content: '' } });
update.examples = current;
setPreset(prevState =>
cleanupPreset({
preset: {
...prevState,
...update
},
endpointsConfig
})
);
};
const removeExample = () => {
let update = {};
let current = preset?.examples.slice() || [];
if (current.length <= 1) {
update.examples = [{ input: { content: '' }, output: { content: '' } }];
setPreset(prevState =>
cleanupPreset({
preset: {
...prevState,
...update
},
endpointsConfig
})
);
return;
}
current.pop();
update.examples = current;
setPreset(prevState =>
cleanupPreset({
preset: {
...prevState,
...update
},
endpointsConfig
})
);
};
const defaultTextProps =
'rounded-md border border-gray-200 focus:border-slate-400 focus:bg-gray-50 bg-transparent text-sm shadow-[0_0_10px_rgba(0,0,0,0.05)] outline-none placeholder:text-gray-400 focus:outline-none focus:ring-gray-400 focus:ring-opacity-20 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-500 dark:bg-gray-700 focus:dark:bg-gray-600 dark:text-gray-50 dark:shadow-[0_0_15px_rgba(0,0,0,0.10)] dark:focus:border-gray-400 dark:focus:outline-none dark:focus:ring-0 dark:focus:ring-gray-400 dark:focus:ring-offset-0';
@ -111,14 +180,35 @@ const EditPresetDialog = ({ open, onOpenChange, preset: _preset, title }) => {
)}
containerClassName="flex w-full resize-none"
/>
{preset?.endpoint === 'google' && (
<Button
type="button"
className="ml-1 flex h-auto w-full bg-transparent px-2 py-1 text-xs font-medium font-normal text-black hover:bg-slate-200 hover:text-black focus:ring-0 focus:ring-offset-0 dark:bg-transparent dark:text-white dark:hover:bg-gray-700 dark:hover:text-white dark:focus:outline-none dark:focus:ring-offset-0"
onClick={triggerExamples}
>
<MessagesSquared className="mr-1 w-[14px]" />
{(showExamples ? 'Hide' : 'Show') + ' Examples'}
</Button>
)}
</div>
</div>
<div className="my-4 w-full border-t border-gray-300 dark:border-gray-500" />
<div className="w-full p-0">
<Settings
preset={preset}
setOption={setOption}
/>
{((preset?.endpoint === 'google' && !showExamples) || preset?.endpoint !== 'google') && (
<Settings
preset={_preset}
setOption={setOption}
/>
)}
{preset?.endpoint === 'google' && showExamples && (
<Examples
examples={preset.examples}
setExample={setExample}
addExample={addExample}
removeExample={removeExample}
edit={true}
/>
)}
</div>
</div>
}

View file

@ -12,12 +12,16 @@ import store from '~/store';
// A preset dialog to show readonly preset values.
const EndpointOptionsDialog = ({ open, onOpenChange, preset: _preset, title }) => {
// const [title, setTitle] = useState('My Preset');
const [preset, setPreset] = useState(_preset);
const [endpointName, setEndpointName] = useState(preset?.endpoint);
const [saveAsDialogShow, setSaveAsDialogShow] = useState(false);
const endpointsConfig = useRecoilValue(store.endpointsConfig);
if (endpointName === 'google') {
setEndpointName('PaLM');
}
const setOption = param => newValue => {
let update = {};
update[param] = newValue;
@ -50,7 +54,7 @@ const EndpointOptionsDialog = ({ open, onOpenChange, preset: _preset, title }) =
onOpenChange={onOpenChange}
>
<DialogTemplate
title={`${title || 'View Options'} - ${preset?.endpoint}`}
title={`${title || 'View Options'} - ${endpointName}`}
className="max-w-full sm:max-w-4xl"
main={
<div className="flex w-full flex-col items-center gap-2">

View file

@ -4,7 +4,13 @@ import CrossIcon from '../svg/CrossIcon';
// import SaveIcon from '../svg/SaveIcon';
import { Save } from 'lucide-react';
function EndpointOptionsPopover({ content, visible, saveAsPreset, switchToSimpleMode }) {
function EndpointOptionsPopover({
content,
visible,
saveAsPreset,
switchToSimpleMode,
additionalButton = null
}) {
const cardStyle =
'shadow-md rounded-md min-w-[75px] font-normal bg-white border-black/10 border dark:bg-gray-700 text-black dark:text-white';
@ -12,29 +18,39 @@ function EndpointOptionsPopover({ content, visible, saveAsPreset, switchToSimple
<>
<div
className={
' endpointOptionsPopover-container absolute bottom-[-10px] flex w-full flex-col items-center justify-center md:px-4' +
' endpointOptionsPopover-container absolute bottom-[-10px] flex w-full flex-col items-center md:px-4' +
(visible ? ' show' : '')
}
>
<div
className={
cardStyle +
' border-s-0 border-d-0 flex w-full flex-col overflow-hidden rounded-none border-t bg-slate-200 px-0 pb-[10px] dark:border-white/10 md:rounded-md md:border lg:w-[736px]'
' border-d-0 flex w-full flex-col overflow-hidden rounded-none border-s-0 border-t bg-slate-200 px-0 pb-[10px] dark:border-white/10 md:rounded-md md:border lg:w-[736px]'
}
>
<div className="flex w-full items-center justify-between bg-slate-100 px-2 py-2 dark:bg-gray-800/60">
<div className="flex w-full items-center bg-slate-100 px-2 py-2 dark:bg-gray-800/60">
{/* <span className="text-xs font-medium font-normal">Advanced settings for OpenAI endpoint</span> */}
<Button
type="button"
className="h-auto bg-transparent px-2 py-1 text-xs font-medium font-normal text-black hover:bg-slate-200 hover:text-black dark:bg-transparent dark:text-white dark:hover:bg-gray-700 dark:hover:text-white"
className="h-auto justify-start bg-transparent px-2 py-1 text-xs font-medium font-normal text-black hover:bg-slate-200 hover:text-black focus:ring-0 dark:bg-transparent dark:text-white dark:hover:bg-gray-700 dark:hover:text-white dark:focus:outline-none dark:focus:ring-offset-0"
onClick={saveAsPreset}
>
<Save className="mr-1 w-[14px]" />
Save as preset
</Button>
{additionalButton && (
<Button
type="button"
className="ml-1 h-auto justify-start bg-transparent px-2 py-1 text-xs font-medium font-normal text-black hover:bg-slate-200 hover:text-black focus:ring-0 focus:ring-offset-0 dark:bg-transparent dark:text-white dark:hover:bg-gray-700 dark:hover:text-white dark:focus:outline-none dark:focus:ring-offset-0"
onClick={additionalButton.handler}
>
{additionalButton.icon}
{additionalButton.label}
</Button>
)}
<Button
type="button"
className="h-auto bg-transparent px-2 py-1 text-xs font-medium font-normal text-black hover:bg-slate-200 hover:text-black dark:bg-transparent dark:text-white dark:hover:bg-gray-700 dark:hover:text-white"
className="ml-auto h-auto bg-transparent px-2 py-1 text-xs font-medium font-normal text-black hover:bg-slate-200 hover:text-black focus:ring-offset-0 dark:bg-transparent dark:text-white dark:hover:bg-gray-700 dark:hover:text-white"
onClick={switchToSimpleMode}
>
<CrossIcon className="mr-1" />

View file

@ -0,0 +1,98 @@
import React from 'react';
import TextareaAutosize from 'react-textarea-autosize';
import { Button } from '~/components/ui/Button.tsx';
import { Label } from '~/components/ui/Label.tsx';
import { Plus, Minus } from 'lucide-react';
import { cn } from '~/utils/';
const defaultTextProps =
'rounded-md border border-gray-200 focus:border-slate-400 focus:bg-gray-50 bg-transparent text-sm shadow-[0_0_10px_rgba(0,0,0,0.05)] outline-none placeholder:text-gray-400 focus:outline-none focus:ring-gray-400 focus:ring-opacity-20 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-500 dark:bg-gray-700 focus:dark:bg-gray-600 dark:text-gray-50 dark:shadow-[0_0_15px_rgba(0,0,0,0.10)] dark:focus:border-gray-400 dark:focus:outline-none dark:focus:ring-0 dark:focus:ring-gray-400 dark:focus:ring-offset-0';
function Examples({ readonly, examples, setExample, addExample, removeExample, edit = false }) {
const maxHeight = edit ? 'max-h-[233px]' : 'max-h-[350px]';
return (
<>
<div className={`${maxHeight} overflow-y-auto`}>
<div
id="examples-grid"
className="grid gap-6 sm:grid-cols-2"
>
{examples.map((example, idx) => (
<React.Fragment key={idx}>
{/* Input */}
<div
className={`col-span-${
examples.length === 1 ? '1' : 'full'
} flex flex-col items-center justify-start gap-6 sm:col-span-1`}
>
<div className="grid w-full items-center gap-2">
<Label
htmlFor={`input-${idx}`}
className="text-left text-sm font-medium"
>
Input <small className="opacity-40">(default: blank)</small>
</Label>
<TextareaAutosize
id={`input-${idx}`}
disabled={readonly}
value={example?.input?.content || ''}
onChange={e => setExample(idx, 'input', e.target.value || null)}
placeholder="Set example input. Example is ignored if empty."
className={cn(
defaultTextProps,
'flex max-h-[300px] min-h-[75px] w-full resize-none px-3 py-2 '
)}
/>
</div>
</div>
{/* Output */}
<div
className={`col-span-${
examples.length === 1 ? '1' : 'full'
} flex flex-col items-center justify-start gap-6 sm:col-span-1`}
>
<div className="grid w-full items-center gap-2">
<Label
htmlFor={`output-${idx}`}
className="text-left text-sm font-medium"
>
Output <small className="opacity-40">(default: blank)</small>
</Label>
<TextareaAutosize
id={`output-${idx}`}
disabled={readonly}
value={example?.output?.content || ''}
onChange={e => setExample(idx, 'output', e.target.value || null)}
placeholder={`Set example output. Example is ignored if empty.`}
className={cn(
defaultTextProps,
'flex max-h-[300px] min-h-[75px] w-full resize-none px-3 py-2 '
)}
/>
</div>
</div>
</React.Fragment>
))}
</div>
</div>
<div className="flex justify-center">
<Button
type="button"
className="mr-2 mt-1 h-auto items-center justify-center bg-transparent px-3 py-2 text-xs font-medium font-normal text-black hover:bg-slate-200 hover:text-black focus:ring-0 focus:ring-offset-0 dark:bg-transparent dark:text-white dark:hover:bg-gray-600 dark:hover:text-white dark:focus:outline-none dark:focus:ring-offset-0"
onClick={removeExample}
>
<Minus className="w-[16px]" />
</Button>
<Button
type="button"
className="mt-1 h-auto items-center justify-center bg-transparent px-3 py-2 text-xs font-medium font-normal text-black hover:bg-slate-200 hover:text-black focus:ring-0 focus:ring-offset-0 dark:bg-transparent dark:text-white dark:hover:bg-gray-600 dark:hover:text-white dark:focus:outline-none dark:focus:ring-offset-0"
onClick={addExample}
>
<Plus className="w-[16px]" />
</Button>
</div>
</>
);
}
export default Examples;

View file

@ -0,0 +1,32 @@
import React from 'react';
import { HoverCardPortal, HoverCardContent } from '~/components/ui/HoverCard.tsx';
const types = {
temp: 'Higher values = more random, while lower values = more focused and deterministic. We recommend altering this or Top P but not both.',
topp: 'Top-p changes how the model selects tokens for output. Tokens are selected from most K (see topK parameter) probable to least until the sum of their probabilities equals the top-p value.',
topk: "Top-k changes how the model selects tokens for output. A top-k of 1 means the selected token is the most probable among all tokens in the model's vocabulary (also called greedy decoding), while a top-k of 3 means that the next token is selected from among the 3 most probable tokens (using temperature).",
maxoutputtokens: " Maximum number of tokens that can be generated in the response. Specify a lower value for shorter responses and a higher value for longer responses."
};
function OptionHover({ type, side }) {
// const options = {};
// if (type === 'pres') {
// options.sideOffset = 45;
// }
return (
<HoverCardPortal>
<HoverCardContent
side={side}
className="w-80 "
// {...options}
>
<div className="space-y-2">
<p className="text-sm text-gray-600 dark:text-gray-300">{types[type]}</p>
</div>
</HoverCardContent>
</HoverCardPortal>
);
}
export default OptionHover;

View file

@ -0,0 +1,271 @@
import { useRecoilValue } from 'recoil';
import TextareaAutosize from 'react-textarea-autosize';
import SelectDropDown from '../../ui/SelectDropDown';
import { Input } from '~/components/ui/Input.tsx';
import { Label } from '~/components/ui/Label.tsx';
import { Slider } from '~/components/ui/Slider.tsx';
import { InputNumber } from '~/components/ui/InputNumber.tsx';
import OptionHover from './OptionHover';
import { HoverCard, HoverCardTrigger } from '~/components/ui/HoverCard.tsx';
import { cn } from '~/utils/';
const defaultTextProps =
'rounded-md border border-gray-200 focus:border-slate-400 focus:bg-gray-50 bg-transparent text-sm shadow-[0_0_10px_rgba(0,0,0,0.05)] outline-none placeholder:text-gray-400 focus:outline-none focus:ring-gray-400 focus:ring-opacity-20 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-500 dark:bg-gray-700 focus:dark:bg-gray-600 dark:text-gray-50 dark:shadow-[0_0_15px_rgba(0,0,0,0.10)] dark:focus:border-gray-400 dark:focus:outline-none dark:focus:ring-0 dark:focus:ring-gray-400 dark:focus:ring-offset-0';
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';
import store from '~/store';
function Settings(props) {
const { readonly, model, modelLabel, promptPrefix, temperature, topP, topK, maxOutputTokens, setOption, edit = false } = props;
const maxHeight = edit ? 'max-h-[233px]' : 'max-h-[350px]';
const endpointsConfig = useRecoilValue(store.endpointsConfig);
const setModel = setOption('model');
const setModelLabel = setOption('modelLabel');
const setPromptPrefix = setOption('promptPrefix');
const setTemperature = setOption('temperature');
const setTopP = setOption('topP');
const setTopK = setOption('topK');
const setMaxOutputTokens = setOption('maxOutputTokens');
const models = endpointsConfig?.['google']?.['availableModels'] || [];
return (
<div className={`${maxHeight} overflow-y-auto`}>
<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">
<SelectDropDown
value={model}
setValue={setModel}
availableValues={models}
disabled={readonly}
className={cn(
defaultTextProps,
'flex w-full resize-none focus:outline-none focus:ring-0 focus:ring-opacity-0 focus:ring-offset-0'
)}
containerClassName="flex w-full resize-none"
/>
</div>
<div className="grid w-full items-center gap-2">
<Label
htmlFor="modelLabel"
className="text-left text-sm font-medium"
>
Custom Name <small className="opacity-40">(default: blank)</small>
</Label>
<Input
id="modelLabel"
disabled={readonly}
value={modelLabel || ''}
onChange={e => setModelLabel(e.target.value || null)}
placeholder="Set a custom name for PaLM2"
className={cn(
defaultTextProps,
'flex h-10 max-h-10 w-full resize-none px-3 py-2 focus:outline-none focus:ring-0 focus:ring-opacity-0 focus:ring-offset-0'
)}
/>
</div>
<div className="grid w-full items-center gap-2">
<Label
htmlFor="promptPrefix"
className="text-left text-sm font-medium"
>
Prompt Prefix <small className="opacity-40">(default: blank)</small>
</Label>
<TextareaAutosize
id="promptPrefix"
disabled={readonly}
value={promptPrefix || ''}
onChange={e => setPromptPrefix(e.target.value || null)}
placeholder="Set custom instructions or context. Ignored if empty."
className={cn(
defaultTextProps,
'flex max-h-[300px] min-h-[100px] w-full resize-none px-3 py-2 '
)}
/>
</div>
</div>
<div className="col-span-1 flex flex-col items-center justify-start gap-6">
<HoverCard openDelay={300}>
<HoverCardTrigger className="grid w-full items-center gap-2">
<div className="flex justify-between">
<Label
htmlFor="temp-int"
className="text-left text-sm font-medium"
>
Temperature <small className="opacity-40">(default: 0.2)</small>
</Label>
<InputNumber
id="temp-int"
disabled={readonly}
value={temperature}
onChange={value => setTemperature(value)}
max={1}
min={0}
step={0.01}
controls={false}
className={cn(
defaultTextProps,
cn(
optionText,
'reset-rc-number-input reset-rc-number-input-text-right h-auto w-12 border-0 group-hover/temp:border-gray-200'
)
)}
/>
</div>
<Slider
disabled={readonly}
value={[temperature]}
onValueChange={value => setTemperature(value[0])}
doubleClickHandler={() => setTemperature(1)}
max={1}
min={0}
step={0.01}
className="flex h-4 w-full"
/>
</HoverCardTrigger>
<OptionHover
type="temp"
side="left"
/>
</HoverCard>
<HoverCard openDelay={300}>
<HoverCardTrigger className="grid w-full items-center gap-2">
<div className="flex justify-between">
<Label
htmlFor="top-p-int"
className="text-left text-sm font-medium"
>
Top P <small className="opacity-40">(default: 0.95)</small>
</Label>
<InputNumber
id="top-p-int"
disabled={readonly}
value={topP}
onChange={value => setTopP(value)}
max={1}
min={0}
step={0.01}
controls={false}
className={cn(
defaultTextProps,
cn(
optionText,
'reset-rc-number-input reset-rc-number-input-text-right h-auto w-12 border-0 group-hover/temp:border-gray-200'
)
)}
/>
</div>
<Slider
disabled={readonly}
value={[topP]}
onValueChange={value => setTopP(value[0])}
doubleClickHandler={() => setTopP(1)}
max={1}
min={0}
step={0.01}
className="flex h-4 w-full"
/>
</HoverCardTrigger>
<OptionHover
type="topp"
side="left"
/>
</HoverCard>
<HoverCard openDelay={300}>
<HoverCardTrigger className="grid w-full items-center gap-2">
<div className="flex justify-between">
<Label
htmlFor="top-k-int"
className="text-left text-sm font-medium"
>
Top K <small className="opacity-40">(default: 40)</small>
</Label>
<InputNumber
id="top-k-int"
disabled={readonly}
value={topK}
onChange={value => setTopK(value)}
max={40}
min={1}
step={0.01}
controls={false}
className={cn(
defaultTextProps,
cn(
optionText,
'reset-rc-number-input reset-rc-number-input-text-right h-auto w-12 border-0 group-hover/temp:border-gray-200'
)
)}
/>
</div>
<Slider
disabled={readonly}
value={[topK]}
onValueChange={value => setTopK(value[0])}
doubleClickHandler={() => setTopK(0)}
max={40}
min={1}
step={0.01}
className="flex h-4 w-full"
/>
</HoverCardTrigger>
<OptionHover
type="topk"
side="left"
/>
</HoverCard>
<HoverCard openDelay={300}>
<HoverCardTrigger className="grid w-full items-center gap-2">
<div className="flex justify-between">
<Label
htmlFor="max-tokens-int"
className="text-left text-sm font-medium"
>
Max Output Tokens <small className="opacity-40">(default: 1024)</small>
</Label>
<InputNumber
id="max-tokens-int"
disabled={readonly}
value={maxOutputTokens}
onChange={value => setMaxOutputTokens(value)}
max={1024}
min={1}
step={1}
controls={false}
className={cn(
defaultTextProps,
cn(
optionText,
'reset-rc-number-input reset-rc-number-input-text-right h-auto w-12 border-0 group-hover/temp:border-gray-200'
)
)}
/>
</div>
<Slider
disabled={readonly}
value={[maxOutputTokens]}
onValueChange={value => setMaxOutputTokens(value[0])}
doubleClickHandler={() => setMaxOutputTokens(0)}
max={1024}
min={1}
step={1}
className="flex h-4 w-full"
/>
</HoverCardTrigger>
<OptionHover
type="maxoutputtokens"
side="left"
/>
</HoverCard>
</div>
</div>
</div>
);
}
export default Settings;

View file

@ -32,7 +32,7 @@ function Settings(props) {
const models = endpointsConfig?.['openAI']?.['availableModels'] || [];
return (
<>
<div className="max-h-[350px] overflow-y-auto">
<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">
@ -264,7 +264,7 @@ function Settings(props) {
</HoverCard>
</div>
</div>
</>
</div>
);
}

View file

@ -2,13 +2,15 @@ import React from 'react';
import OpenAISettings from './OpenAI/Settings.jsx';
import BingAISettings from './BingAI/Settings.jsx';
import GoogleSettings from './Google/Settings.jsx';
// A preset dialog to show readonly preset values.
const Settings = ({ preset, ...props }) => {
const renderSettings = () => {
const { endpoint } = preset || {};
// console.log('preset', preset);
if (endpoint === 'openAI')
if (endpoint === 'openAI') {
return (
<OpenAISettings
model={preset?.model}
@ -21,7 +23,7 @@ const Settings = ({ preset, ...props }) => {
{...props}
/>
);
else if (endpoint === 'bingAI')
} else if (endpoint === 'bingAI') {
return (
<BingAISettings
toneStyle={preset?.toneStyle}
@ -31,7 +33,24 @@ const Settings = ({ preset, ...props }) => {
{...props}
/>
);
else return <div className="text-black dark:text-white">Not implemented</div>;
} else if (endpoint === 'google') {
return (
<GoogleSettings
model={preset?.model}
modelLabel={preset?.modelLabel}
promptPrefix={preset?.promptPrefix}
examples={preset?.examples}
temperature={preset?.temperature}
topP={preset?.topP}
topK={preset?.topK}
maxOutputTokens={preset?.maxOutputTokens}
edit={true}
{...props}
/>
);
} else {
return <div className="text-black dark:text-white">Not implemented</div>;
}
};
return renderSettings();