allow custom api url, key, model

This commit is contained in:
josc146 2023-06-20 23:24:51 +08:00
parent 285e8b1577
commit bae9ae6551
5 changed files with 130 additions and 10 deletions

View File

@ -151,5 +151,7 @@
"Open": "打开", "Open": "打开",
"DPI Scaling": "显示缩放", "DPI Scaling": "显示缩放",
"Restart the app to apply DPI Scaling.": "重启应用以使显示缩放生效", "Restart the app to apply DPI Scaling.": "重启应用以使显示缩放生效",
"Restart": "重启" "Restart": "重启",
"API Chat Model Name": "API聊天模型名",
"API Completion Model Name": "API补全模型名"
} }

View File

@ -154,17 +154,20 @@ const ChatPanel: FC = observer(() => {
setTimeout(scrollToBottom); setTimeout(scrollToBottom);
let answer = ''; let answer = '';
chatSseController = new AbortController(); chatSseController = new AbortController();
fetchEventSource(`http://127.0.0.1:${port}/chat/completions`, // https://api.openai.com/v1/chat/completions || http://127.0.0.1:${port}/chat/completions fetchEventSource( // https://api.openai.com/v1/chat/completions || http://127.0.0.1:${port}/chat/completions
commonStore.settings.apiUrl ?
commonStore.settings.apiUrl + '/v1/chat/completions' :
`http://127.0.0.1:${port}/chat/completions`,
{ {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
Authorization: `Bearer sk-` Authorization: `Bearer ${commonStore.settings.apiKey}`
}, },
body: JSON.stringify({ body: JSON.stringify({
messages, messages,
stream: true, stream: true,
model: 'gpt-3.5-turbo' model: commonStore.settings.apiChatModelName // 'gpt-3.5-turbo'
}), }),
signal: chatSseController?.signal, signal: chatSseController?.signal,
onmessage(e) { onmessage(e) {

View File

@ -190,17 +190,20 @@ const CompletionPanel: FC = observer(() => {
let answer = ''; let answer = '';
completionSseController = new AbortController(); completionSseController = new AbortController();
fetchEventSource(`http://127.0.0.1:${port}/completions`, // https://api.openai.com/v1/completions || http://127.0.0.1:${port}/completions fetchEventSource( // https://api.openai.com/v1/completions || http://127.0.0.1:${port}/completions
commonStore.settings.apiUrl ?
commonStore.settings.apiUrl + '/v1/completions' :
`http://127.0.0.1:${port}/completions`,
{ {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
Authorization: `Bearer sk-` Authorization: `Bearer ${commonStore.settings.apiKey}`
}, },
body: JSON.stringify({ body: JSON.stringify({
prompt, prompt,
stream: true, stream: true,
model: 'text-davinci-003', model: commonStore.settings.apiCompletionModelName, // 'text-davinci-003'
max_tokens: params.maxResponseToken, max_tokens: params.maxResponseToken,
temperature: params.temperature, temperature: params.temperature,
top_p: params.topP, top_p: params.topP,

View File

@ -34,6 +34,10 @@ export type SettingsType = {
dpiScaling: number dpiScaling: number
customModelsPath: string customModelsPath: string
customPythonPath: string customPythonPath: string
apiUrl: string
apiKey: string
apiChatModelName: string
apiCompletionModelName: string
} }
export const Settings: FC = observer(() => { export const Settings: FC = observer(() => {
@ -139,8 +143,11 @@ export const Settings: FC = observer(() => {
}); });
}} /> }} />
} /> } />
<Accordion collapsible> <Accordion collapsible openItems={!commonStore.advancedCollapsed && 'advanced'} onToggle={(e, data) => {
<AccordionItem value="1"> if (data.value === 'advanced')
commonStore.setAdvancedCollapsed(!commonStore.advancedCollapsed);
}}>
<AccordionItem value="advanced">
<AccordionHeader ref={advancedHeaderRef} size="large">{t('Advanced')}</AccordionHeader> <AccordionHeader ref={advancedHeaderRef} size="large">{t('Advanced')}</AccordionHeader>
<AccordionPanel> <AccordionPanel>
<div className="flex flex-col gap-2 overflow-hidden"> <div className="flex flex-col gap-2 overflow-hidden">
@ -164,6 +171,102 @@ export const Settings: FC = observer(() => {
}); });
}} /> }} />
} /> } />
<Labeled label={'API URL'}
content={
<div className="flex gap-2">
<Input style={{ minWidth: 0 }} className="grow" value={commonStore.settings.apiUrl}
onChange={(e, data) => {
commonStore.setSettings({
apiUrl: data.value
});
}} />
<Dropdown style={{ minWidth: 0 }} listbox={{ style: { minWidth: 0 } }}
value="..." selectedOptions={[]} expandIcon={null}
onOptionSelect={(_, data) => {
commonStore.setSettings({
apiUrl: data.optionValue
});
if (data.optionText === 'OpenAI') {
if (commonStore.settings.apiChatModelName === 'rwkv')
commonStore.setSettings({
apiChatModelName: 'gpt-3.5-turbo'
});
if (commonStore.settings.apiCompletionModelName === 'rwkv')
commonStore.setSettings({
apiCompletionModelName: 'text-davinci-003'
});
}
}}>
<Option value="https://api.openai.com">OpenAI</Option>
<Option value="">Clear</Option>
</Dropdown>
</div>
} />
<Labeled label={'API Key'}
content={
<Input className="grow" placeholder="sk-" value={commonStore.settings.apiKey}
onChange={(e, data) => {
commonStore.setSettings({
apiKey: data.value
});
}} />
} />
<Labeled label={t('API Chat Model Name')}
content={
<div className="flex gap-2">
<Input style={{ minWidth: 0 }} className="grow" placeholder="rwkv"
value={commonStore.settings.apiChatModelName}
onChange={(e, data) => {
commonStore.setSettings({
apiChatModelName: data.value
});
}} />
<Dropdown style={{ minWidth: 0 }} listbox={{ style: { minWidth: 0 } }}
value="..." selectedOptions={[]} expandIcon={null}
onOptionSelect={(_, data) => {
if (data.optionValue) {
commonStore.setSettings({
apiChatModelName: data.optionValue
});
}
}}>
{
['rwkv', 'gpt-4', 'gpt-4-0613', 'gpt-4-32k', 'gpt-4-32k-0613', 'gpt-3.5-turbo', 'gpt-3.5-turbo-0613', 'gpt-3.5-turbo-16k', 'gpt-3.5-turbo-16k-0613']
.map((v, i) =>
<Option key={i} value={v}>{v}</Option>
)
}
</Dropdown>
</div>
} />
<Labeled label={t('API Completion Model Name')}
content={
<div className="flex gap-2">
<Input style={{ minWidth: 0 }} className="grow" placeholder="rwkv"
value={commonStore.settings.apiCompletionModelName}
onChange={(e, data) => {
commonStore.setSettings({
apiCompletionModelName: data.value
});
}} />
<Dropdown style={{ minWidth: 0 }} listbox={{ style: { minWidth: 0 } }}
value="..." selectedOptions={[]} expandIcon={null}
onOptionSelect={(_, data) => {
if (data.optionValue) {
commonStore.setSettings({
apiCompletionModelName: data.optionValue
});
}
}}>
{
['rwkv', 'text-davinci-003', 'text-davinci-002', 'text-curie-001', 'text-babbage-001', 'text-ada-001']
.map((v, i) =>
<Option key={i} value={v}>{v}</Option>
)
}
</Dropdown>
</div>
} />
</div> </div>
</AccordionPanel> </AccordionPanel>
</AccordionItem> </AccordionItem>

View File

@ -56,6 +56,7 @@ class CommonStore {
// downloads // downloads
downloadList: DownloadStatus[] = []; downloadList: DownloadStatus[] = [];
// settings // settings
advancedCollapsed: boolean = true;
settings: SettingsType = { settings: SettingsType = {
language: getUserLanguage(), language: getUserLanguage(),
darkMode: !isSystemLightMode(), darkMode: !isSystemLightMode(),
@ -65,7 +66,11 @@ class CommonStore {
host: '127.0.0.1', host: '127.0.0.1',
dpiScaling: 100, dpiScaling: 100,
customModelsPath: './models', customModelsPath: './models',
customPythonPath: '' customPythonPath: '',
apiUrl: '',
apiKey: 'sk-',
apiChatModelName: 'rwkv',
apiCompletionModelName: 'rwkv'
}; };
// about // about
about: AboutContent = manifest.about; about: AboutContent = manifest.about;
@ -188,6 +193,10 @@ class CommonStore {
setCurrentInput(value: string) { setCurrentInput(value: string) {
this.currentInput = value; this.currentInput = value;
} }
setAdvancedCollapsed(value: boolean) {
this.advancedCollapsed = value;
}
} }
export default new CommonStore(); export default new CommonStore();