index.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <!--
  2. - Copyright (c) 2024 LangChat. TyCoding All Rights Reserved.
  3. -
  4. - Licensed under the GNU Affero General Public License, Version 3 (the "License");
  5. - you may not use this file except in compliance with the License.
  6. - You may obtain a copy of the License at
  7. -
  8. - https://www.gnu.org/licenses/agpl-3.0.html
  9. -
  10. - Unless required by applicable law or agreed to in writing, software
  11. - distributed under the License is distributed on an "AS IS" BASIS,
  12. - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. - See the License for the specific language governing permissions and
  14. - limitations under the License.
  15. -->
  16. <script lang="ts" setup>
  17. import { BasicForm, useForm } from '@/components/Form';
  18. import { getSchemas, LLMProviders } from './columns';
  19. import { isNullOrWhitespace } from '@/utils/is';
  20. import { add, del, list as getModels, update } from '@/api/aigc/model';
  21. import { useDialog, useMessage } from 'naive-ui';
  22. import { onMounted } from 'vue';
  23. import { ModelTypeEnum } from '@/api/models';
  24. import { ref } from 'vue-demi';
  25. const message = useMessage();
  26. const dialog = useDialog();
  27. const ms = useMessage();
  28. const schemas = ref();
  29. const isLocalEmbedding = ref(false);
  30. const [register, { setFieldsValue, getFieldsValue }] = useForm({
  31. labelWidth: 120,
  32. gridProps: { cols: 1 },
  33. layout: 'horizontal',
  34. submitButtonText: '提交',
  35. });
  36. onMounted(async () => {
  37. const data = await getModels({ type: ModelTypeEnum.EMBEDDING });
  38. if (data != null && data.length >= 1) {
  39. setFieldsValue({ ...data[0] });
  40. schemas.value = getSchemas(data[0].provider);
  41. } else {
  42. isLocalEmbedding.value = true;
  43. schemas.value = getSchemas('');
  44. }
  45. });
  46. function onChange(val) {
  47. schemas.value = getSchemas(val);
  48. }
  49. async function onSubmit(values: any) {
  50. if (values !== false) {
  51. const data = { ...values };
  52. if (isNullOrWhitespace(data.id)) {
  53. await add(data);
  54. ms.success('新增成功');
  55. } else {
  56. await update(data);
  57. ms.success('修改成功');
  58. }
  59. } else {
  60. ms.error('请完善表单');
  61. }
  62. }
  63. function onUseLocal(val: boolean) {
  64. if (val) {
  65. dialog.info({
  66. title: '提示',
  67. content: `启用本地Embedding模型将会删除下面表单中的模型配置,请谨慎操作`,
  68. positiveText: '确定',
  69. negativeText: '取消',
  70. onPositiveClick: async () => {
  71. const data = getFieldsValue();
  72. if (data.id !== undefined) {
  73. await del(data.id);
  74. }
  75. message.success('本地模型已启用');
  76. },
  77. onNegativeClick: () => {},
  78. });
  79. } else {
  80. message.success('本地模型已禁用');
  81. }
  82. }
  83. </script>
  84. <template>
  85. <div class="flex gap-16 mb-10 h-full">
  86. <n-card class="w-1/4 h-full">
  87. <div class="pb-4 text-lg text-gray-800">注意事项</div>
  88. <n-alert
  89. class="w-full mb-4 mt-2 min-alert"
  90. title="默认提供本地化Embedding向量模型方案:BgeSmallEnV15QuantizedEmbeddingModel,此模型仅占用20M的内存。此模型使用384向量纬度"
  91. type="warning"
  92. />
  93. <n-alert
  94. class="w-full mb-4 mt-2 min-alert"
  95. title="如果不使用默认Embedding模型则需要配置供应商信息。Dimensions代表向量纬度,不同的模型配置不一样,此值和VectorStore的配置要完全对应,如果在application.yml已经配置了VectorStore的Dimensions参数,那么这里也应该保持相同,否则需要删除VectorStore表重新启动项目"
  96. type="warning"
  97. />
  98. <n-alert
  99. class="w-full mb-4 mt-2 min-alert"
  100. title="一旦切换Embedding模型,很可能由于向量纬度不同导致VectorStore中原有数据不可用,请谨慎操作"
  101. type="warning"
  102. />
  103. </n-card>
  104. <div class="flex-1 mr-[30vh]">
  105. <div class="mb-4">
  106. <n-tag class="mr-2 rounded-2xl px-5" type="success">
  107. 是否启用本地Embedding向量模型:
  108. </n-tag>
  109. <n-switch v-model:value="isLocalEmbedding" @update:value="onUseLocal">
  110. <template #checked> 启用 </template>
  111. <template #unchecked> 不启用 </template>
  112. </n-switch>
  113. </div>
  114. <BasicForm :schemas="schemas" class="mt-5" @register="register" @submit="onSubmit">
  115. <template #providerSlot="{ model, field }">
  116. <n-select
  117. v-model:value="model[field]"
  118. :options="LLMProviders"
  119. label-field="name"
  120. value-field="model"
  121. @change:value="onChange"
  122. />
  123. </template>
  124. </BasicForm>
  125. </div>
  126. </div>
  127. </template>
  128. <style lang="less" scoped></style>