更新 setting 页面

This commit is contained in:
yuruo
2024-07-05 17:09:13 +08:00
parent 01571aefff
commit 513a62a182
7 changed files with 114 additions and 43 deletions

View File

@@ -14,7 +14,9 @@ ipcMain.handle("shortCut", (_event: IpcMainInvokeEvent) => {
export function registerSearchShortCut(){
globalShortcut.unregisterAll()
const ret = findOne(`select * from config where id=1`) as {content: string}
const shortCut = JSON.parse(ret.content).shortCut as string
console.log(ret)
const shortCut = JSON.parse(ret.content).shortcut as string
console.log(shortCut)
if (shortCut && globalShortcut.isRegistered(shortCut)){
dialog.showErrorBox('提示', '快捷键注册失败,请更换')
return false

View File

@@ -27,9 +27,9 @@ export const config = {
id: 0,
options: {
initShow: true,
width: 600,
height: 400,
openDevTools: false,
width: 800,
height: 650,
openDevTools: true,
frame: true,
transparent: false,
hash: '/#config'

View File

@@ -1,24 +1,23 @@
import { Button, Form, Input, Select, Space } from 'antd';
import { Button, Form, Input, Select, Space, message } from 'antd';
import styles from './styles.module.scss'
import { useEffect, useState } from 'react';
import { useLoaderData } from 'react-router-dom';
import { localServerBaseUrl } from '@renderer/config';
const { Option } = Select;
const layout = {
labelCol: { span: 6 },
wrapperCol: { span: 16 },
};
const tailLayout = {
wrapperCol: { offset: 6, span: 16 },
};
export const Setting = () => {
const [form] = Form.useForm();
export function Setting(){
const [form] = Form.useForm();
const config = useLoaderData() as ConfigDataType
form.setFieldsValue(config);
const { Option } = Select;
const tailLayout = {
wrapperCol: { offset: 6, span: 16 },
};
const [keys, setKeys] = useState<string[]>([])
const onModelChange = (value: string) => {
switch (value) {
case 'openai':
form.setFieldsValue({ model: 'gpt-4-turbo', base_url:"https://api.openai.com/v1"});
break;
case 'ollama':
form.setFieldsValue({ model: 'ollama/llama2',api_base: "http://localhost:11434" });
@@ -27,24 +26,84 @@ export const Setting = () => {
}
};
const onFinish = (values: any) => {
console.log(values);
const onFinish = async (values: any) => {
// 注册快捷键
window.api.shortCut()
await window.api.sql(`update config set content=@content where id = 1`,
'update',
{
content: JSON.stringify(values)
})
// window.close();
};
const onReset = () => {
form.resetFields();
const onClose = () => {
window.close()
};
return (
<div className='flex justify-center items-center h-screen'>
<div className={styles.settingPage}>
<h1>Setting</h1>
<Form
{...layout}
form={form}
name="control-hooks"
onFinish={onFinish}
style={{ maxWidth: 900 }}
>
>
<section>
<h5></h5>
<Form.Item name="shortcut" label="呼出快捷键" rules={[{ required: true }]}>
<Input
type="text"
readOnly
onKeyDown={(e) => {
if (e.metaKey || e.ctrlKey || e.altKey) {
const code = e.code.replace(/Left|Right|Key|Digit/, '')
if (keys.includes(code)) return
keys.push(code)
setKeys(keys)
// 如果以数字或字母或者空格结尾
if (code.match(/^(\w|\s)$/gi)) {
e.currentTarget.value = keys.join('+')
form.setFieldsValue({shortcut: e.currentTarget.value})
setKeys([])
}
}
}}
/>
</Form.Item>
</section>
<section>
<div className='flex flex-row justify-between items-center mb-3'>
<h5></h5>
<Button
onClick={async () => {
const hide = message.loading('检测中...', 0);
try {
const res = await fetch(`${localServerBaseUrl}/llm`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(
{ "messages": [{ "role": "user", "content": "hello" }],
"llm_config": JSON.stringify(form.getFieldValue("llm"))}),
}
)
hide();
if (res.ok) {
message.success('连接成功')
} else {
message.error(`连接失败,请检查配置信息是否正确:\n${res.statusText}`)
}
} catch (error) {
hide();
message.error(`连接失败,请检查配置信息是否正确:\n${error}`)
}
}}></Button>
</div>
<Form.Item name="format" label="格式" rules={[{ required: true }]}>
<Select
placeholder="选择格式一般OpenAI格式为万能格式"
@@ -56,7 +115,7 @@ export const Setting = () => {
</Select>
</Form.Item>
<Form.Item name="model" label="model" rules={[{ required: true }]}>
<Form.Item name={["llm", "model"]} label="model" rules={[{ required: true }]}>
<Input />
</Form.Item>
@@ -67,10 +126,10 @@ export const Setting = () => {
{({ getFieldValue }) =>
getFieldValue('format') === 'openai' ? (
<div>
<Form.Item name="api_key" label="api_key" rules={[{ required: true }]}>
<Form.Item name={["llm", "api_key"]} label="api_key" rules={[{ required: true }]}>
<Input />
</Form.Item>
<Form.Item name="base_url" label="base_url" rules={[{ required: false }]}>
<Form.Item name={["llm", "base_url"]} label="base_url" rules={[{ required: false }]}>
<Input />
</Form.Item>
</div>
@@ -84,22 +143,26 @@ export const Setting = () => {
>
{({ getFieldValue }) =>
getFieldValue('format') === 'ollama' ? (
<Form.Item name="api_base" label="api_base" rules={[{ required: false }]}>
<Form.Item name={["llm", "api_base"]} label="api_base" rules={[{ required: false }]}>
<Input />
</Form.Item>
) : null
}
</Form.Item>
<Form.Item {...tailLayout} className='mt-10'>
</section>
<div className='mt-10 flex justify-center items-center'>
<Form.Item {...tailLayout} >
<Space>
<Button htmlType="button" onClick={onClose} className='mr-5'>
</Button>
<Button type="primary" htmlType="submit" >
Submit
</Button>
<Button htmlType="button" onClick={onReset}>
Reset
</Button>
</Space>
</Form.Item>
</div>
</Form>
</div>
);

View File

@@ -25,7 +25,6 @@ export const Setting = () => {
if (keys.includes(code)) return
keys.push(code)
setKeys(keys)
// 如果以数字或字母或者空格结尾
if (code.match(/^(\w|\s)$/gi)) {
e.currentTarget.value = keys.join('+')

View File

@@ -6,7 +6,7 @@
section{
h5 {
@apply text-xs font-bold mb-2 text-slate-700 opacity-80;
@apply text-sm font-bold mb-8 text-slate-700 opacity-80;
}
h6 {
@apply text-sm mb-2 text-slate-700 opacity-80;

6
app/types.d.ts vendored
View File

@@ -25,9 +25,11 @@ type ConfigType = {
type ConfigDataType = {
shortCut: string
format: string
llm: {
model: string
api_key: string
base_url: string
api_key?: string
base_url?: string
api_base?: string
}
}

View File

@@ -7,15 +7,20 @@ home_bp = Blueprint('llm', __name__)
@home_bp.route('/llm', methods=["POST"])
def llm():
config = get_config()
messages = request.get_json()["messages"]
isStream = request.get_json().get("isStream", False)
llm_config = request.get_json().get("llm_config", None)
if llm_config:
config = json.loads(llm_config)
else:
config = json.loads(get_config())["llm"]
if isStream:
def generate():
response = completion(
messages=messages,
stream=True,
**json.loads(config)["llm"]
**config
)
for part in response:
yield part.choices[0].delta.content or ""
@@ -23,7 +28,7 @@ def llm():
else:
res = completion(
messages=messages,
**json.loads(config)["llm"]
**config
)
return {
"content": res.choices[0].message.content