You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

319 lines
13 KiB

<script lang="ts" setup>
import { onMounted, ref } from "vue";
import {
getSystemConfig,
setSystemConfig,
} from "@/system/config";
import { notifySuccess, notifyError } from "@/util/msg";
import { t } from "@/i18n/index";
import { OpenDirDialog } from "@/util/goutil";
import { useModelStore } from "@/stores/model.ts";
const modelStore = useModelStore();
// 参数 描述 值类型 示例用法
// mirostat 启用Mirostat采样以控制困惑度。默认值:0,其中0=禁用,1=Mirostat,2=Mirostat 2.0 int mirostat 0
// mirostat_eta 影响算法根据生成文本的反馈进行调整的速度。较低的学习率将导致调整速度变慢,而较高的学习率将使算法响应更迅速。默认值:0.1 float mirostat_eta 0.1
// mirostat_tau 控制输出的连贯性和多样性之间的平衡。更低的值将产生更集中和连贯的文本。默认值:5.0 float mirostat_tau 5.0
// num_ctx 设置用于生成下一个令牌的上下文窗口大小。默认值:2048 int num_ctx 4096
// repeat_last_n 设置模型应回顾多远以防止重复。(默认:64,0=禁用,-1=num_ctx) int repeat_last_n 64
// repeat_penalty 设置对重复的惩罚程度。较高的值(例如,1.5)会更强地惩罚重复,而较低的值(例如,0.9)则较为宽容。默认值:1.1 float repeat_penalty 1.1
// temperature 模型的温度。增加温度会使模型回答更具创造性。默认值:0.8 float temperature 0.7
// seed 设置用于生成的随机数种子。将其设置为特定数字将使模型在相同的提示下生成相同的文本。默认值:0 int seed 42
// stop 设置使用的停止序列。当遇到此模式时,LLM将停止生成文本并返回。可以在模型文件中通过指定多个单独的stop参数来设置多个停止模式。 string stop "AI助手:"
// tfs_z 尾部自由采样用于减少输出中较不可能出现的令牌的影响。较高的值(例如,2.0)将更大程度地减少这种影响,而1.0的值则禁用此设置。默认值:1 float tfs_z 1
// num_predict 生成文本时预测的最大令牌数量。(默认:128,-1=无限生成,-2=填充上下文) int num_predict 42
// top_k 减少生成无意义内容的概率。较高的值(例如,100)将给出更多样化的答案,而较低的值(例如,10)则更为保守。默认值:40 int top_k 40
// top_p 与top-k一起工作。较高的值(例如,0.95)将产生更多样化的文本,而较低的值(例如,0.5)将生成更集中且保守的文本。默认值:0.9 float top_p 0.9
const hoverTxt = {
dataDir: t('aisetting.tips_dataDir'),
apiUrl: t('aisetting.tips_apiUrl'),
contextLength: t("setting.tips_contextLength"),
top_k: t('aisetting.tips_top_k'),
top_p: t('aisetting.tips_top_p'),
temperature: t('aisetting.tips_temperature'),
frequency_penalty: t('aisetting.tips_frequency_penalty'),
presence_penalty: t('aisetting.tips_presence_penalty'),
num_predict: t('aisetting.tips_num_predict'),
num_keep: t('aisetting.tips_num_keep'),
};
// const systemStore = useSystemStore();
const config: any = ref({});
//const chatConfig: any = ref({});
const currentsModel: any = ref({});
const pageLoading = ref(true);
import type { TabsPaneContext } from "element-plus";
const activeName = ref("system");
const activeModel = ref("chat");
const handleClick = (tab: TabsPaneContext, event: Event) => {
console.log(tab, event);
};
const saveConfig = async () => {
try {
await fetch(config.value.apiUrl, {
method: "GET",
mode: "no-cors",
});
} catch (error) {
notifyError(t('common.urlError'));
return;
}
let postData: any = []
if (config.value.dataDir.trim() != "") {
postData.push({
name: "dataDir",
value: config.value.dataDir.trim(),
})
}
if (config.value.ollamaUrl.trim() != "") {
postData.push({
name: "ollamaUrl",
value: config.value.ollamaUrl.trim(),
})
}
if (postData.length > 0) {
const postDatas = {
method: "POST",
body: JSON.stringify(postData),
};
const res: any = await fetch(config.value.apiUrl + "/system/setting", postDatas);
//console.log(res)
if (!res || !res.ok) {
notifyError(t('common.saveError'));
return;
}
const ret = await res.json();
if (ret && ret.code != 0) {
notifyError(ret.message);
return;
}
}
await changeConfig();
//await modelStore.getModelList();
//modelStore.updateCurrentModels(modelList.value);
notifySuccess(t('common.saveSuccess'));
};
const changeConfig = async () => {
//console.log(v)
//setSystemKey('llmType',v)
setSystemConfig(config.value);
await initConfig();
};
const initConfig = async () => {
config.value = getSystemConfig();
//currentsModel.value = getCurrents();
//chatConfig.value = getChatConfig();
};
onMounted(async () => {
await initConfig();
await modelStore.getModelList();
//modelList.value = modelStore.modelList;
//console.log(modelList.value)
pageLoading.value = false;
});
async function changeDir() {
const path: any = await OpenDirDialog();
//console.log(path)
config.value.dataDir = path;
}
</script>
<template>
<div v-loading="pageLoading">
<el-tabs v-model="activeName" class="setting-tabs" style="margin: 12px" @tab-click="handleClick">
<el-tab-pane :label="t('aisetting.modelSetting')" name="system">
<el-scrollbar class="scrollbarSettingHeight">
<el-form label-width="150px" style="padding: 0 30px 50px 0">
<el-form-item :label="t('aisetting.dataDir')">
<div class="slider-container">
<el-input v-model="config.dataDir" :placeholder="t('aisetting.localDirHolder')" prefix-icon="Menu"
@click="changeDir()" clearable></el-input>
<el-popover placement="left" :width="400" trigger="click">
<template #reference>
<el-icon :size="22">
<InfoFilled />
</el-icon>
</template>
<template #default>
<div v-html="hoverTxt.dataDir"></div>
</template>
</el-popover>
</div>
</el-form-item>
<el-form-item :label="t('aisetting.serverUrl')">
<div class="slider-container">
<el-input v-model="config.aiUrl" :placeholder="t('aisetting.serverUrl')" prefix-icon="Notification"
clearable></el-input>
<el-popover placement="left" :width="400" trigger="click">
<template #reference>
<el-icon :size="22">
<InfoFilled />
</el-icon>
</template>
<template #default>
<div v-html="hoverTxt.apiUrl"></div>
</template>
</el-popover>
</div>
</el-form-item>
<el-form-item :label="t('aisetting.ollamaUrl')">
<div class="slider-container">
<el-input v-model="config.ollamaUrl" :placeholder="t('aisetting.ollamaUrl')" prefix-icon="Notification"
clearable></el-input>
</div>
</el-form-item>
<el-form-item>
<el-button @click="saveConfig" type="info" plain>
{{ t("common.confim") }}
</el-button>
</el-form-item>
</el-form>
</el-scrollbar>
</el-tab-pane>
<el-tab-pane :label="t('aisetting.defModel')" name="modelDef">
<el-scrollbar class="scrollbarSettingHeight">
<el-form label-width="150px" style="padding: 0 30px 50px 0">
<el-form-item :label="t('model.' + item)" v-for="(item, index) in modelStore.cateList" :key="index">
<el-select v-model="currentsModel[item]" @change="(val: any) => modelStore.setCurrentModel(item, val)">
<el-option v-for="(el, key) in modelStore.getCurrentModelList(item)" :key="key"
:label="el.model" :value="el.model" />
</el-select>
</el-form-item>
</el-form>
</el-scrollbar>
</el-tab-pane>
<el-tab-pane :label="t('aisetting.chatSetting')" name="chatSetting">
<el-tabs tab-position="left" v-model="activeModel" style="height: 490px" class="setting-tabs">
<el-tab-pane :name="item.key" :label="t('model.' + item.key)" v-for="item in modelStore.chatConfig">
<el-form label-width="100px" style="width: 500px">
<el-form-item :label="t('aisetting.contextLength')" v-if="item.contextLength" class="inline-layout">
<div class="slider-container">
<el-slider v-model="item.contextLength" :max="10" :min="1" :step="1" />
<el-popover placement="left" :width="400" trigger="click">
<template #reference>
<el-icon :size="22">
<InfoFilled />
</el-icon>
</template>
<template #default>
<div v-html="hoverTxt.contextLength"></div>
</template>
</el-popover>
</div>
</el-form-item>
<el-form-item :label="t('aisetting.num_predict')" class="inline-layout">
<div class="slider-container">
<el-slider v-model="item.num_predict" :max="5000" :min="1" />
<el-popover placement="left" :width="400" trigger="click">
<template #reference>
<el-icon :size="22">
<InfoFilled />
</el-icon>
</template>
<template #default>
<div v-html="hoverTxt.num_predict"></div>
</template>
</el-popover>
</div>
</el-form-item>
<el-form-item :label="t('aisetting.num_keep')" class="inline-layout">
<div class="slider-container">
<el-slider v-model="item.num_keep" :max="500" :min="1" />
<el-popover placement="left" :width="400" trigger="click">
<template #reference>
<el-icon :size="22">
<InfoFilled />
</el-icon>
</template>
<template #default>
<div v-html="hoverTxt.num_keep"></div>
</template>
</el-popover>
</div>
</el-form-item>
<el-form-item :label="t('aisetting.top_k')" class="inline-layout">
<div class="slider-container">
<el-slider v-model="item.top_k" :max="100" :min="1" />
<el-popover placement="left" :width="400" trigger="click">
<template #reference>
<el-icon :size="22">
<InfoFilled />
</el-icon>
</template>
<template #default>
<div v-html="hoverTxt.top_k"></div>
</template>
</el-popover>
</div>
</el-form-item>
<el-form-item :label="t('aisetting.top_p')" class="inline-layout">
<div class="slider-container">
<el-slider v-model="item.top_p" :max="1" :min="0.01" :step="0.01" />
<el-popover placement="left" :width="400" trigger="click">
<template #reference>
<el-icon :size="22">
<InfoFilled />
</el-icon>
</template>
<template #default>
<div v-html="hoverTxt.top_p"></div>
</template>
</el-popover>
</div>
</el-form-item>
<el-form-item :label="t('aisetting.temperature')" class="inline-layout">
<div class="slider-container">
<el-slider v-model="item.temperature" :max="0.99" :min="0.01" :step="0.01" />
<el-popover placement="left" :width="400" trigger="click">
<template #reference>
<el-icon :size="22">
<InfoFilled />
</el-icon>
</template>
<template #default>
<div v-html="hoverTxt.temperature"></div>
</template>
</el-popover>
</div>
</el-form-item>
</el-form>
</el-tab-pane>
</el-tabs>
</el-tab-pane>
</el-tabs>
</div>
</template>
<style>
.setting-tabs>.el-tabs__content {
padding: 0px;
color: #6b778c;
font-size: 32px;
font-weight: 600;
}
.scrollbarSettingHeight {
height: 80vh;
padding-bottom: 30px;
}
.inline-layout {
display: flex;
align-items: center;
/* 如果有必要,可以在这里添加额外的样式来调整表单项的整体表现 */
}
.slider-container {
display: flex;
align-items: center;
width: 100%;
}
.slider-container .el-icon {
cursor: pointer;
margin-left: 20px;
}
</style>