Merge branch 'master' of http://192.168.5.5:10010/r/web/flow_web
6个文件已删除
1个文件已添加
1 文件已重命名
9个文件已修改
| | |
| | | configArcoResolverPlugin(), |
| | | configImageminPlugin(), |
| | | ], |
| | | server: { |
| | | open: true, // 项目启动后,自动打开 |
| | | fs: { |
| | | strict: true, |
| | | }, |
| | | proxy: { |
| | | '/base': { |
| | | target: 'http://192.168.20.116:8089', |
| | | changeOrigin: true, |
| | | ws: true, |
| | | }, |
| | | '/api': { |
| | | target: 'http://192.168.20.116:8089', |
| | | changeOrigin: true, |
| | | ws: true, |
| | | }, |
| | | '/api/v1': { |
| | | target: 'http://192.168.20.116:8089', |
| | | changeOrigin: true, |
| | | ws: true, |
| | | }, |
| | | }, |
| | | }, |
| | | build: { |
| | | rollupOptions: { |
| | | output: { |
| | |
| | | } |
| | | |
| | | export function logout() { |
| | | return axios.post<LoginRes>('/api/user/logout'); |
| | | return axios.post<LoginRes>('/base/logout'); |
| | | } |
| | | |
| | | export function getUserInfo() { |
| | |
| | | path:'sessionManager', |
| | | name:"sessionManager", |
| | | meta:{ |
| | | locale: '会话管理', |
| | | requiresAuth: true, |
| | | hideInMenu:true, |
| | | roles: ['*'], |
| | | activeMenu:'session' |
| | | }, |
| | | component:()=>import('@/views/session/sessionManager/index.vue'), |
| | | }, |
| | | { |
| | | path:'sessionRecordsManager', |
| | | name:"sessionRecordsManager", |
| | | meta:{ |
| | | locale: '会话记录', |
| | | requiresAuth: true, |
| | | roles: ['*'], |
| | | }, |
| | | component:()=>import('@/views/session/sessionRecordsManager/index.vue'), |
| | | } |
| | | ] |
| | | }; |
| | |
| | | :bordered="false" |
| | | :style="{ 'width': '100%', 'height': '900px', 'overflow-y': 'auto' }" |
| | | > |
| | | <a-button @click="() => onIconClick(null)">新增父级菜单</a-button> |
| | | <a-tree |
| | | class="tree-demo" |
| | | draggable |
| | |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { ref } from 'vue'; |
| | | import { IconPlus } from '@arco-design/web-vue/es/icon'; |
| | | import { |
| | | Resource, |
| | | ResourceAdd, |
| | | ResourceById, |
| | | ResourceDelete, |
| | | ResourceList, |
| | | ResourceUpdate, |
| | | } from '@/api/authority'; |
| | | import Authheader from '@/views/authority/components/authheader.vue'; |
| | | import { Modal } from '@arco-design/web-vue'; |
| | | import { ref } from "vue"; |
| | | import { IconPlus } from "@arco-design/web-vue/es/icon"; |
| | | import { Resource, ResourceAdd, ResourceById, ResourceDelete, ResourceList, ResourceUpdate } from "@/api/authority"; |
| | | import Authheader from "@/views/authority/components/authheader.vue"; |
| | | import { Modal } from "@arco-design/web-vue"; |
| | | |
| | | let visible = ref(false); |
| | | let treeData = ref([]); |
| | | let showLine = ref(true); |
| | | let menuTips = ref(['权限管理', '资源']); |
| | | const fieldNames = { value: 'key', label: 'value' }; |
| | | // 0目录 1菜单 2按钮 |
| | | let options = ref([ |
| | | { |
| | | key: '3', |
| | | value: '目录', |
| | | }, |
| | | { |
| | | key: '0', |
| | | value: '菜单', |
| | | }, |
| | | { |
| | | key: '1', |
| | | value: '按钮', |
| | | }, |
| | | ]); |
| | | let resourceform = ref<Resource>({ |
| | | component: '', |
| | | createTime: '', |
| | | description: '', |
| | | icon: '', |
| | | menuId: '', |
| | | menuName: '', |
| | | menuType: '', |
| | | orderNum: '', |
| | | parentId: '', |
| | | parentName: '', |
| | | children: [], |
| | | path: '', |
| | | perms: '', |
| | | status: '', |
| | | syesourcetype: '', |
| | | target: '', |
| | | updateTime: '', |
| | | let visible = ref(false); |
| | | let treeData = ref([]); |
| | | let showLine = ref(true); |
| | | let menuTips = ref(["权限管理", "资源"]); |
| | | const fieldNames = { value: "key", label: "value" }; |
| | | // 0目录 1菜单 2按钮 |
| | | let options = ref([ |
| | | { |
| | | key: "3", |
| | | value: "目录" |
| | | }, |
| | | { |
| | | key: "0", |
| | | value: "菜单" |
| | | }, |
| | | { |
| | | key: "1", |
| | | value: "按钮" |
| | | } |
| | | ]); |
| | | let resourceform = ref<Resource>({ |
| | | component: "", |
| | | createTime: "", |
| | | description: "", |
| | | icon: "", |
| | | menuId: "", |
| | | menuName: "", |
| | | menuType: "", |
| | | orderNum: "", |
| | | parentId: "", |
| | | parentName: "", |
| | | children: [], |
| | | path: "", |
| | | perms: "", |
| | | status: "", |
| | | syesourcetype: "", |
| | | target: "", |
| | | updateTime: "" |
| | | }); |
| | | |
| | | const onIconClick = (nodeData) => { |
| | | if (nodeData) { |
| | | resourceform.value.parentId = nodeData.menuId; |
| | | resourceform.value.parentName = nodeData.menuName; |
| | | } |
| | | resourceform.value.component = ""; |
| | | resourceform.value.createTime = ""; |
| | | resourceform.value.description = ""; |
| | | resourceform.value.icon = ""; |
| | | resourceform.value.menuId = ""; |
| | | resourceform.value.menuName = ""; |
| | | resourceform.value.menuType = ""; |
| | | resourceform.value.orderNum = "0"; |
| | | resourceform.value.path = ""; |
| | | resourceform.value.perms = ""; |
| | | resourceform.value.status = ""; |
| | | resourceform.value.syesourcetype = ""; |
| | | |
| | | visible.value = true; |
| | | }; |
| | | |
| | | const addresource = async () => { |
| | | await ResourceAdd({ |
| | | ...resourceform.value |
| | | } as unknown as Resource).then((res) => { |
| | | ResourceData(""); |
| | | }); |
| | | }; |
| | | |
| | | const onIconClickDelete = (nodeData) => { |
| | | ResourceDelete(nodeData.menuId).then(() => { |
| | | ResourceData(""); |
| | | }); |
| | | }; |
| | | |
| | | const showDetail = (id) => { |
| | | ResourceById(id).then((res) => { |
| | | resourceform.value = { ...res.data }; |
| | | }); |
| | | }; |
| | | const editresource = () => { |
| | | ResourceUpdate({ |
| | | ...resourceform.value |
| | | } as unknown as Resource).then((res) => { |
| | | ResourceData(""); |
| | | Modal.success({ |
| | | title: "保存成功", |
| | | content: "保存成功" |
| | | }); |
| | | }); |
| | | }; |
| | | const reset = (id) => { |
| | | ResourceById(id).then((res) => { |
| | | resourceform.value = { ...res.data }; |
| | | }); |
| | | }; |
| | | |
| | | const onDrop = ({ dragNode, dropNode, dropPosition }) => { |
| | | const data = treeData.value; |
| | | ResourceUpdate({ |
| | | orderNum: "0", |
| | | parentId: dropNode.menuId, |
| | | menuId: dragNode.menuId |
| | | }); |
| | | const loop = (data, key, callback) => { |
| | | data.some((item, index, arr) => { |
| | | if (item.menuId === key) { |
| | | callback(item, index, arr); |
| | | return true; |
| | | } |
| | | if (item.children) { |
| | | return loop(item.children, key, callback); |
| | | } |
| | | return false; |
| | | }); |
| | | }; |
| | | |
| | | loop(data, dragNode.menuId, (_, index, arr) => { |
| | | arr.splice(index, 1); |
| | | }); |
| | | |
| | | const onIconClick = (nodeData) => { |
| | | resourceform.value.parentId = nodeData.menuId; |
| | | resourceform.value.component = ''; |
| | | resourceform.value.createTime = ''; |
| | | resourceform.value.description = ''; |
| | | resourceform.value.icon = ''; |
| | | resourceform.value.menuId = ''; |
| | | resourceform.value.menuName = ''; |
| | | resourceform.value.menuType = ''; |
| | | resourceform.value.orderNum = '0'; |
| | | resourceform.value.parentName = nodeData.menuName; |
| | | resourceform.value.path = ''; |
| | | resourceform.value.perms = ''; |
| | | resourceform.value.status = ''; |
| | | resourceform.value.syesourcetype = ''; |
| | | |
| | | visible.value = true; |
| | | }; |
| | | |
| | | const addresource = async () => { |
| | | await ResourceAdd({ |
| | | ...resourceform.value, |
| | | } as unknown as Resource).then((res) => { |
| | | ResourceData(''); |
| | | if (dropPosition === 0) { |
| | | loop(data, dropNode.menuId, (item) => { |
| | | item.children = item.children || []; |
| | | item.children.push(dragNode); |
| | | }); |
| | | }; |
| | | |
| | | const onIconClickDelete = (nodeData) => { |
| | | ResourceDelete(nodeData.menuId).then(() => { |
| | | ResourceData(''); |
| | | } else { |
| | | loop(data, dropNode.menuId, (_, index, arr) => { |
| | | arr.splice(dropPosition < 0 ? index : index + 1, 0, dragNode); |
| | | }); |
| | | }; |
| | | } |
| | | }; |
| | | |
| | | const showDetail = (id) => { |
| | | ResourceById(id).then((res) => { |
| | | resourceform.value = { ...res.data }; |
| | | }); |
| | | }; |
| | | const editresource = () => { |
| | | ResourceUpdate({ |
| | | ...resourceform.value, |
| | | } as unknown as Resource).then((res) => { |
| | | ResourceData(''); |
| | | Modal.success({ |
| | | title: '保存成功', |
| | | content: '保存成功', |
| | | }); |
| | | }); |
| | | }; |
| | | const reset = (id) => { |
| | | ResourceById(id).then((res) => { |
| | | resourceform.value = { ...res.data }; |
| | | }); |
| | | }; |
| | | const handleCancel = (type) => { |
| | | if (type == 1) { |
| | | visible.value = false; |
| | | } |
| | | }; |
| | | |
| | | const onDrop = ({ dragNode, dropNode, dropPosition }) => { |
| | | const data = treeData.value; |
| | | ResourceUpdate({ |
| | | orderNum: '0', |
| | | parentId: dropNode.menuId, |
| | | menuId: dragNode.menuId, |
| | | }); |
| | | const loop = (data, key, callback) => { |
| | | data.some((item, index, arr) => { |
| | | if (item.menuId === key) { |
| | | callback(item, index, arr); |
| | | return true; |
| | | } |
| | | if (item.children) { |
| | | return loop(item.children, key, callback); |
| | | } |
| | | return false; |
| | | }); |
| | | }; |
| | | const ResourceData = async (key) => { |
| | | await ResourceList(key).then((res) => { |
| | | treeData.value = [...res.rows]; |
| | | }); |
| | | }; |
| | | |
| | | loop(data, dragNode.menuId, (_, index, arr) => { |
| | | arr.splice(index, 1); |
| | | }); |
| | | |
| | | if (dropPosition === 0) { |
| | | loop(data, dropNode.menuId, (item) => { |
| | | item.children = item.children || []; |
| | | item.children.push(dragNode); |
| | | }); |
| | | } else { |
| | | loop(data, dropNode.menuId, (_, index, arr) => { |
| | | arr.splice(dropPosition < 0 ? index : index + 1, 0, dragNode); |
| | | }); |
| | | } |
| | | }; |
| | | |
| | | const handleCancel = (type) => { |
| | | if (type == 1) { |
| | | visible.value = false; |
| | | } |
| | | }; |
| | | |
| | | const ResourceData = async (key) => { |
| | | await ResourceList(key).then((res) => { |
| | | treeData.value = [...res.rows]; |
| | | }); |
| | | }; |
| | | |
| | | ResourceData(''); |
| | | ResourceData(""); |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .tree-demo :deep(.tree-node-dropover) > :deep(.arco-tree-node-title), |
| | | .tree-demo :deep(.tree-node-dropover) > :deep(.arco-tree-node-title):hover { |
| | | animation: blinkBg 0.4s 2; |
| | | .tree-demo :deep(.tree-node-dropover) > :deep(.arco-tree-node-title), |
| | | .tree-demo :deep(.tree-node-dropover) > :deep(.arco-tree-node-title):hover { |
| | | animation: blinkBg 0.4s 2; |
| | | } |
| | | |
| | | @keyframes blinkBg { |
| | | 0% { |
| | | background-color: transparent; |
| | | } |
| | | |
| | | @keyframes blinkBg { |
| | | 0% { |
| | | background-color: transparent; |
| | | } |
| | | |
| | | 100% { |
| | | background-color: var(--color-primary-light-1); |
| | | } |
| | | 100% { |
| | | background-color: var(--color-primary-light-1); |
| | | } |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <div class="container"> |
| | | <authheader :items="menuTips"></authheader> |
| | | <a-card ref="account" class="general-card" :title="$t('menu.user.title')"> |
| | | <a-card ref="account" class="general-card"> |
| | | <a-row> |
| | | <a-col :flex="2"></a-col> |
| | | <a-col :flex="1"> |
| | | <a-form :model="formModel"> |
| | | <a-form :model="formModel" style="margin-top: 30px"> |
| | | <a-form-item field="name"> |
| | | <a-input |
| | | v-model="formModel.name" |
| | |
| | | </a-form-item> |
| | | </a-form> |
| | | </a-col> |
| | | <a-divider style="height: 40px" direction="vertical" /> |
| | | <a-col :flex="'200px'" style="text-align: right"> |
| | | <a-col :flex="'200px'" style="text-align: right;margin-top: 30px"> |
| | | <a-button @click="reset" style="margin-right: 20px"> |
| | | <template #icon> |
| | | <icon-refresh /> |
New file |
| | |
| | | <template> |
| | | <a-button |
| | | v-if="typeAngint == 'add'" |
| | | type="primary" |
| | | @click="handleClick" |
| | | style="margin-left: 10px"> |
| | | <template #icon> |
| | | <icon-plus /> |
| | | </template> |
| | | 新建智能体 |
| | | </a-button> |
| | | <a-button |
| | | v-if="typeAngint == 'edit'" |
| | | type="text" |
| | | size="small" |
| | | @click="editClick" |
| | | > |
| | | <template #icon> |
| | | <icon-tool /> |
| | | </template> |
| | | </a-button> |
| | | <a-modal |
| | | v-model:visible="visible" |
| | | title="智能体配置" |
| | | @before-open="handleOpened" |
| | | @cancel="handleCancel" |
| | | :ok-loading="loading" |
| | | @before-ok="handleBeforeOk" |
| | | :footer="true" |
| | | title-align="start" |
| | | width="600px" |
| | | > |
| | | <a-row class=""> |
| | | <a-col :span="24"> |
| | | <a-tabs type="capsule" size="large"> |
| | | <a-tab-pane key="1" title="助理设置"> |
| | | <a-divider style="margin-bottom: 20px;margin-top: 0" /> |
| | | <div style="width: 100%;" :style="{height:height}"> |
| | | <a-form |
| | | ref="formRef" |
| | | :rules="rules" |
| | | :model="form" |
| | | @submit="handleSubmit" |
| | | :style="{ width: '90%', margin: '0 auto' }" |
| | | > |
| | | <a-form-item field="name" label="智能体名称"> |
| | | <a-input v-model="form.name" placeholder="请输入名称" /> |
| | | </a-form-item> |
| | | <a-form-item label="智能体图标"> |
| | | <a-space direction="vertical" :style="{ width: '100%' }"> |
| | | <a-upload |
| | | :auto-upload="false" |
| | | :fileList="file ? [file] : []" |
| | | :show-file-list="false" |
| | | @change="onChange" |
| | | @progress="onProgress" |
| | | > |
| | | <template #upload-button> |
| | | <div |
| | | :class="`arco-upload-list-item${ |
| | | file && file.status === 'error' ? ' arco-upload-list-item-error' : '' |
| | | }`" |
| | | > |
| | | <div |
| | | class="arco-upload-list-picture custom-upload-avatar" |
| | | v-if="file && file.url" |
| | | > |
| | | <img :src="file.url" /> |
| | | <div class="arco-upload-list-picture-mask"> |
| | | <IconEdit /> |
| | | </div> |
| | | <a-progress |
| | | v-if="file.status === 'uploading' && file.percent < 100" |
| | | :percent="file.percent" |
| | | type="circle" |
| | | size="mini" |
| | | :style="{ |
| | | position: 'absolute', |
| | | left: '50%', |
| | | top: '50%', |
| | | transform: 'translateX(-50%) translateY(-50%)', |
| | | }" |
| | | /> |
| | | </div> |
| | | <div class="arco-upload-picture-card" v-else> |
| | | <div class="arco-upload-picture-card-text"> |
| | | <IconPlus /> |
| | | <div style="margin-top: 10px; font-weight: 600">上传</div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | </a-upload> |
| | | </a-space> |
| | | </a-form-item> |
| | | <a-form-item label="空回复"> |
| | | <a-input v-model="form.prompt_config.empty_response" placeholder="" /> |
| | | </a-form-item> |
| | | <a-form-item label="设置开场白"> |
| | | <a-textarea |
| | | v-model="form.prompt_config.prologue" |
| | | placeholder="" |
| | | style="height: 100px" |
| | | /> |
| | | </a-form-item> |
| | | <a-form-item label="显示引文"> |
| | | <a-space direction="vertical" > |
| | | <a-switch v-model="form.prompt_config.quote" size="small" /> |
| | | </a-space> |
| | | </a-form-item> |
| | | <a-form-item label="Self-RAG"> |
| | | <a-space direction="vertical"> |
| | | <a-switch v-model="form.prompt_config.self_rag" size="small" /> |
| | | </a-space> |
| | | </a-form-item> |
| | | <a-form-item field="kb_ids" label="知识库"> |
| | | <a-select |
| | | v-model="form.kb_ids" |
| | | placeholder="请选择 ..." |
| | | multiple |
| | | > |
| | | <a-option |
| | | v-for="item in tabs" |
| | | :key="item.id" |
| | | :value="item.id" |
| | | > |
| | | {{ item.name }} |
| | | </a-option> |
| | | </a-select> |
| | | </a-form-item> |
| | | <!-- <a-form-item>--> |
| | | <!-- <div style="width: 100%; text-align: right">--> |
| | | <!-- <a-button @click="visible = false">取消</a-button>--> |
| | | <!-- <a-button style="margin-left: 10px" type="primary" html-type="submit"--> |
| | | <!-- >确定</a-button--> |
| | | <!-- >--> |
| | | <!-- </div>--> |
| | | <!-- </a-form-item>--> |
| | | </a-form> |
| | | </div> |
| | | </a-tab-pane> |
| | | <a-tab-pane key="2" title="提示引擎"> |
| | | <a-divider style="margin-bottom: 20px;margin-top: 0" /> |
| | | <a-scrollbar style="width: 100%;overflow: auto" :style="{height:height}"> |
| | | <a-form |
| | | ref="formRef1" |
| | | :rules="rules" |
| | | :model="form" |
| | | @submit="handleSubmit" |
| | | :style="{ width: '90%', margin: '0 auto' }" |
| | | > |
| | | <a-form-item field="prompt_config.system" label="系统"> |
| | | <a-textarea |
| | | v-model="form.prompt_config.system" |
| | | placeholder="" |
| | | style="height: 180px" |
| | | /> |
| | | </a-form-item> |
| | | <a-divider style="margin: 0;margin-bottom: 10px" /> |
| | | <a-form-item label="相似度阈值"> |
| | | <a-slider v-model="form.similarity_threshold" :step="0.01" :min="0" :max="1" /> |
| | | </a-form-item> |
| | | <a-form-item label="关键字相似度权重"> |
| | | <a-slider v-model="form.vector_similarity_weight" :step="0.01" :min="0" :max="1" /> |
| | | </a-form-item> |
| | | <a-form-item label="Top N"> |
| | | <a-slider v-model="form.top_n" :min="0" :max="30" /> |
| | | </a-form-item> |
| | | <a-form-item label="Rerank模型" > |
| | | <a-space direction="vertical" size="large"> |
| | | <a-select :size="'large'" v-model="form.rerank_id" placeholder="请选择 ..." allow-clear> |
| | | <a-optgroup :label="index" v-for="(item,index) in rankModelList" :key=index> |
| | | <a-option |
| | | v-for="(obj) in item" |
| | | :key="obj.fid" |
| | | :disabled="!obj.available" |
| | | :value="obj.llm_name" |
| | | > |
| | | {{obj.llm_name}} |
| | | </a-option> |
| | | </a-optgroup> |
| | | </a-select> |
| | | </a-space> |
| | | </a-form-item> |
| | | <a-form-item v-if="form.rerank_id" label="Top-K"> |
| | | <a-slider v-model="form.top_k" :min="1" :max="2048" /> |
| | | </a-form-item> |
| | | <a-form-item label="变量"> |
| | | <div style="width: 100%;text-align: right" > |
| | | <a-button type="outline" @click="addVariable" style="" size="mini" shape="round"> |
| | | 新建 |
| | | </a-button> |
| | | </div> |
| | | </a-form-item> |
| | | <a-form-item label=""> |
| | | <a-table |
| | | :columns="columns" |
| | | :data="form.prompt_config.parameters" |
| | | style="width: 100%" |
| | | > |
| | | <template #key="{ record }"> |
| | | <a-input v-model="record.key" placeholder="" /> |
| | | </template> |
| | | <template #optional="{ record }"> |
| | | <a-switch v-model="record.optional" size="small" /> |
| | | </template> |
| | | <template #action="{ record }"> |
| | | <a-button type="text" @click="deleteParameters(record)" style="margin-left: 0px" size="small"> |
| | | <template #icon> |
| | | <icon-delete /> |
| | | </template> |
| | | </a-button> |
| | | </template> |
| | | </a-table> |
| | | </a-form-item> |
| | | </a-form> |
| | | </a-scrollbar> |
| | | </a-tab-pane> |
| | | <a-tab-pane key="3" title="模型设置"> |
| | | <a-divider style="margin-bottom: 20px;margin-top: 0" /> |
| | | <div style="width: 100%;" :style="{height:height}"> |
| | | <a-form |
| | | ref="formRef2" |
| | | :rules="rules" |
| | | :model="form" |
| | | @submit="handleSubmit" |
| | | :style="{ width: '90%', margin: '0 auto' }" |
| | | > |
| | | <a-form-item field="llm_id" label="模型"> |
| | | <a-space direction="vertical" size="large"> |
| | | <a-select :size="'large'" field="llm_id" v-model="form.llm_id" style="width: 400px" placeholder="请选择"> |
| | | <a-optgroup |
| | | :label="index" |
| | | v-for="(item, index) in modelList" |
| | | :key="index" |
| | | > |
| | | <a-option |
| | | v-for="obj in item" |
| | | :key="obj.fid" |
| | | :disabled="!obj.available" |
| | | :value="obj.llm_id" |
| | | > |
| | | {{ obj.llm_name }} |
| | | </a-option> |
| | | </a-optgroup> |
| | | </a-select> |
| | | </a-space> |
| | | </a-form-item> |
| | | <a-divider style="margin-bottom: 20px;margin-top: 0" /> |
| | | <a-form-item label="自由"> |
| | | <a-select default-value="2" :style="{width:'400px'}" placeholder=""> |
| | | <a-option value="1">即兴创作</a-option> |
| | | <a-option value="2">精确</a-option> |
| | | <a-option value="3">平衡</a-option> |
| | | </a-select> |
| | | </a-form-item> |
| | | <a-form-item label="温度"> |
| | | <a-switch size="small" /> |
| | | <a-space direction="vertical" size="large"> |
| | | <a-slider v-model="form.llm_setting.temperature" :step="0.01" :min="0" :max="1" :style="{ width: '350px', marginLeft: '20px' }" show-input /> |
| | | </a-space> |
| | | </a-form-item> |
| | | <a-form-item label="top P"> |
| | | <a-switch size="small" /> |
| | | <a-space direction="vertical" size="large"> |
| | | <a-slider v-model="form.llm_setting.top_p" :step="0.01" :min="0" :max="1" :style="{ width: '350px', marginLeft: '20px' }" show-input /> |
| | | </a-space> |
| | | </a-form-item> |
| | | <a-form-item label="出席处罚"> |
| | | <a-switch size="small" /> |
| | | <a-space direction="vertical" size="large"> |
| | | <a-slider v-model="form.llm_setting.presence_penalty" :step="0.01" :min="0" :max="1" :style="{ width: '350px', marginLeft: '20px' }" show-input /> |
| | | </a-space> |
| | | </a-form-item> |
| | | <a-form-item label="频率处罚"> |
| | | <a-switch size="small" /> |
| | | <a-space direction="vertical" size="large"> |
| | | <a-slider v-model="form.llm_setting.frequency_penalty" :step="0.01" :min="0" :max="1" :style="{ width: '350px', marginLeft: '20px' }" show-input /> |
| | | </a-space> |
| | | </a-form-item> |
| | | <a-form-item label="最大token数"> |
| | | <a-switch size="small" /> |
| | | <a-space direction="vertical" size="large"> |
| | | <a-slider v-model="form.llm_setting.max_tokens" :min="0" :max="2048" :style="{ width: '350px', marginLeft: '20px' }" show-input /> |
| | | </a-space> |
| | | </a-form-item> |
| | | </a-form> |
| | | </div> |
| | | </a-tab-pane> |
| | | </a-tabs> |
| | | </a-col> |
| | | </a-row> |
| | | </a-modal> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { onMounted, onBeforeMount, reactive, ref, nextTick } from "vue"; |
| | | import { kbdocumentupload, queryKbList, queryModelList } from "@/api/kbList"; |
| | | import useLoading from "@/hooks/loading"; |
| | | import { Message } from "@arco-design/web-vue"; |
| | | import { dialogSet } from "@/api/Agent"; |
| | | import EventBus from "@/utils/EventBus"; |
| | | const { loading,setLoading } = useLoading(true); |
| | | const visible = ref(false); |
| | | const modelList = ref({}); |
| | | const rankModelList = ref({}); |
| | | let tabs = ref([]); |
| | | const file = ref(); |
| | | const formRef = ref(); |
| | | const formRef1 = ref(); |
| | | const formRef2 = ref(); |
| | | const form = reactive({ |
| | | name: "", |
| | | icon: "", |
| | | language: "English", |
| | | prompt_config: { |
| | | empty_response: "", |
| | | prologue: "你好! 我是你的助理,有什么可以帮到你的吗?", |
| | | quote: true, |
| | | self_rag: true, |
| | | system: "你是一个智能助手,请总结知识库的内容来回答问题,请列举知识库中的数据详细回答。当所有知识库内容都与问题无关时,你的回答必须包括“知识库中未找到您要的答案!”这句话。" + |
| | | "回答需要考虑聊天历史。\n 以下是知识库:\n {knowledge}\n 以上是知识库。", |
| | | parameters: [ |
| | | { |
| | | index: 0, |
| | | key: "knowledge", |
| | | optional: false |
| | | } |
| | | ] |
| | | }, |
| | | kb_ids: [], |
| | | llm_id: "qwen-plus", |
| | | llm_setting: { |
| | | temperature: 0.1, |
| | | top_p: 0.3, |
| | | presence_penalty: 0.4, |
| | | frequency_penalty: 0.7, |
| | | max_tokens: 512 |
| | | }, |
| | | similarity_threshold: 0.2, |
| | | vector_similarity_weight: 0.30000000000000004, |
| | | top_n: 8, |
| | | rerank_id:'', |
| | | top_k:1024, |
| | | }); |
| | | const height = ref('calc(100vh - 520px)'); |
| | | const props = defineProps(['typeAngint', 'formData']); |
| | | const emit = defineEmits(['queryList']); |
| | | const columns = [ |
| | | { |
| | | title: '关键字', |
| | | dataIndex: 'key', |
| | | slotName: 'key', |
| | | }, |
| | | { |
| | | title: '可选', |
| | | dataIndex: 'optional', |
| | | slotName: 'optional', |
| | | }, |
| | | { |
| | | title: '操作', |
| | | dataIndex: 'action', |
| | | slotName: 'action', |
| | | }, |
| | | ]; |
| | | |
| | | const formatter = (value) => { |
| | | return `${(value / 100).toFixed(2)}` |
| | | }; |
| | | |
| | | const onChange = (_, currentFile) => { |
| | | file.value = currentFile; |
| | | convertImageToBase64(file.value.file).then((result) => { |
| | | form.icon = result; |
| | | }); |
| | | }; |
| | | |
| | | function convertImageToBase64(file) { |
| | | return new Promise((resolve, reject) => { |
| | | const reader = new FileReader(); |
| | | reader.onloadend = function() { |
| | | resolve(reader.result); |
| | | }; |
| | | reader.onerror = reject; |
| | | reader.readAsDataURL(file); |
| | | }); |
| | | } |
| | | |
| | | const onProgress = (currentFile) => { |
| | | file.value = currentFile; |
| | | }; |
| | | |
| | | const rules = { |
| | | name: [ |
| | | { |
| | | required: true, |
| | | message: "名称不允许为空" |
| | | } |
| | | ], |
| | | "prompt_config.system": [ |
| | | { |
| | | required: true, |
| | | message: "系统不允许为空" |
| | | } |
| | | ], |
| | | llm_id: [ |
| | | { |
| | | required: true, |
| | | message: '模型不能为空', |
| | | }, |
| | | ], |
| | | kb_ids: [ |
| | | { |
| | | required: true, |
| | | message: '知识库不能为空', |
| | | }, |
| | | ], |
| | | }; |
| | | |
| | | const handleSubmit = ({ values, errors }) => { |
| | | console.log("values:", values, "\nerrors:", errors); |
| | | if (!errors) { |
| | | |
| | | } |
| | | }; |
| | | |
| | | const handleClick = () => { |
| | | visible.value = true; |
| | | }; |
| | | defineExpose({ |
| | | handleClick |
| | | }); |
| | | |
| | | const handleCancel = () => { |
| | | visible.value = false; |
| | | formRef.value.resetFields(); |
| | | formRef1.value.resetFields(); |
| | | formRef2.value.resetFields(); |
| | | form.name = ""; |
| | | emit('queryList'); |
| | | }; |
| | | |
| | | const handleOpened = (el) => { |
| | | // Object.assign(form,{ |
| | | // name: '',// 用户名 |
| | | // nameJoin: '',// 昵称 |
| | | // post: '',// 岗位 |
| | | // txt: '',// 备注 |
| | | // }); |
| | | formRef.value.resetFields(); |
| | | form.name = ""; |
| | | form.prompt_config.system = "你是一个智能助手,请总结知识库的内容来回答问题,请列举知识库中的数据详细回答。当所有知识库内容都与问题无关时,你的回答必须包括“知识库中未找到您要的答案!”这句话。" + |
| | | "回答需要考虑聊天历史。\n 以下是知识库:\n {knowledge}\n 以上是知识库。"; |
| | | formRef.value.resetFields(); |
| | | formRef1.value.resetFields(); |
| | | formRef2.value.resetFields(); |
| | | }; |
| | | |
| | | |
| | | const handleBeforeOk = async (done) => { |
| | | formRef.value.validate().then(res => { |
| | | console.log('res:', res) |
| | | }) |
| | | formRef1.value.validate().then(res => { |
| | | console.log('res:', res) |
| | | }) |
| | | formRef2.value.validate().then(res => { |
| | | console.log('res:', res) |
| | | }) |
| | | if (form.name && form.kb_ids.length>0 && form.prompt_config.system && form.llm_id) { |
| | | let title = '创建成功'; |
| | | let formNew = { ...form }; |
| | | if(formNew.rerank_id){ |
| | | delete formNew.top_k; |
| | | } |
| | | |
| | | if(formNew.rerank_id){ |
| | | delete formNew.top_k; |
| | | } |
| | | |
| | | if (props.typeAngint == 'edit') { |
| | | formNew.dialog_id = form.id; |
| | | delete formNew.id; |
| | | delete formNew.off; |
| | | title = '修改成功'; |
| | | } |
| | | setLoading(true) |
| | | try { |
| | | const data = await dialogSet(formNew); |
| | | console.log(data, 'data'); |
| | | if (data.code == 0){ |
| | | Message.success(title); |
| | | handleCancel(); |
| | | EventBus.emit('queryList'); |
| | | }else { |
| | | Message.error(data.msg); |
| | | } |
| | | done(true); |
| | | setLoading(false) |
| | | } catch (err) { |
| | | // you can report use errorHandler or other |
| | | setLoading(false) |
| | | } |
| | | }else { |
| | | Message.warning('请填写必填项'); |
| | | done(false) |
| | | } |
| | | }; |
| | | |
| | | const editClick = (data) => { |
| | | visible.value = true; |
| | | nextTick(()=>{ |
| | | console.log(props.formData,'传入数据'); |
| | | Object.assign(form, props.formData); |
| | | console.log(form,'表单数据'); |
| | | }) |
| | | }; |
| | | |
| | | const addVariable = () => { |
| | | form.prompt_config.parameters.push({ |
| | | index: form.prompt_config.parameters.length, |
| | | key: "", |
| | | optional: true |
| | | }); |
| | | nextTick(() => { |
| | | formRef.value.validate(); |
| | | }); |
| | | } |
| | | |
| | | const deleteParameters = (record) => { |
| | | // console.log(record, 'record'); |
| | | // console.log(form.prompt_config.parameters); |
| | | form.prompt_config.parameters = form.prompt_config.parameters.filter(item => item.index !== record.index); |
| | | |
| | | } |
| | | |
| | | |
| | | const queryModel = async (params) => { |
| | | try { |
| | | const data = await queryModelList(params); |
| | | console.log(data.data, '大模型列表'); |
| | | modelList.value = data.data; |
| | | rankModelList.value = { |
| | | BAAI: [data.data.BAAI[1]], |
| | | Jina: data.data.Jina, |
| | | youdao: data.data.youdao |
| | | }; |
| | | } catch (err) { |
| | | // you can report use errorHandler or other |
| | | } finally { |
| | | } |
| | | }; |
| | | |
| | | |
| | | const knowledgeData = async (params = { page: 1, page_size: 20 }) => { |
| | | setLoading(true); |
| | | try { |
| | | const { data } = await queryKbList(params); |
| | | console.log(data, 'data'); |
| | | nextTick(() => { |
| | | tabs.value = data; |
| | | console.log(tabs.value, 'tabs'); |
| | | }); |
| | | } catch (err) { |
| | | // you can report use errorHandler or other |
| | | } finally { |
| | | setLoading(false); |
| | | } |
| | | }; |
| | | |
| | | onBeforeMount(() => { |
| | | queryModel({}); |
| | | knowledgeData(); |
| | | }); |
| | | onMounted(() => {}); |
| | | |
| | | |
| | | |
| | | |
| | | </script> |
| | | <style lang="less" scoped> |
| | | :deep(.arco-tabs-nav-tab-list) { |
| | | width: 100%; |
| | | |
| | | .arco-tabs-tab { |
| | | width: 33%; |
| | | |
| | | .arco-tabs-tab-title { |
| | | width: 100%; |
| | | display: inline-block; |
| | | text-align: center; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| | |
| | | |
| | | const editClick = (data) => { |
| | | visible.value = true; |
| | | |
| | | console.log(props.formData); |
| | | Object.assign(form, props.formData); |
| | | console.log(form); |
| | |
| | | style="width: 240px" |
| | | @change="queryList" |
| | | /> |
| | | <agent-config typeAngint="add"></agent-config> |
| | | </div> |
| | | <a-divider style="margin: 10px 0" /> |
| | | <a-row justify="space-between"> |
| | | <a-col :span="24"> |
| | | <div style="display: flex; flex-wrap: wrap"> |
| | | <div |
| | | class="card-wrap" |
| | | style="cursor: pointer" |
| | | @click="handleAdd" |
| | | > |
| | | <a-card :bordered="false" hoverable> |
| | | <div style="margin-top: 30px; text-align: center"> |
| | | <a-avatar style="background: #3370ff"> |
| | | <icon-plus /> |
| | | </a-avatar> |
| | | </div> |
| | | <div class="arco-card-body-content"> |
| | | <div style="text-align: center; margin-top: 10px"> |
| | | 新建智能体 |
| | | </div> |
| | | <div |
| | | style=" |
| | | text-align: center; |
| | | margin-top: 10px; |
| | | font-size: 12px; |
| | | color: #999999; |
| | | " |
| | | > |
| | | 通过描述角色和任务来创建你的智能体<br /> |
| | | 智能体可以调用多个工作流和工具 |
| | | </div> |
| | | </div> |
| | | <add-agent ref="addAgents"></add-agent> |
| | | <!-- <div style="position: absolute; bottom: 1rem; right: 1rem;">--> |
| | | <!-- <a-space>--> |
| | | <!-- </a-space>--> |
| | | <!-- </div>--> |
| | | </a-card> |
| | | </div> |
| | | <!-- <div--> |
| | | <!-- class="card-wrap"--> |
| | | <!-- style="cursor: pointer"--> |
| | | <!-- @click="handleAdd"--> |
| | | <!-- >--> |
| | | <!-- <a-card :bordered="false" hoverable>--> |
| | | <!-- <div style="margin-top: 30px; text-align: center">--> |
| | | <!-- <a-avatar style="background: #3370ff">--> |
| | | <!-- <icon-plus />--> |
| | | <!-- </a-avatar>--> |
| | | <!-- </div>--> |
| | | <!-- <div class="arco-card-body-content">--> |
| | | <!-- <div style="text-align: center; margin-top: 10px">--> |
| | | <!-- 新建智能体--> |
| | | <!-- </div>--> |
| | | <!-- <div--> |
| | | <!-- style="--> |
| | | <!-- text-align: center;--> |
| | | <!-- margin-top: 10px;--> |
| | | <!-- font-size: 12px;--> |
| | | <!-- color: #999999;--> |
| | | <!-- "--> |
| | | <!-- >--> |
| | | <!-- 通过描述角色和任务来创建你的智能体<br />--> |
| | | <!-- 智能体可以调用多个工作流和工具--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <!-- <add-agent ref="addAgents"></add-agent>--> |
| | | <!-- <!– <div style="position: absolute; bottom: 1rem; right: 1rem;">–>--> |
| | | <!-- <!– <a-space>–>--> |
| | | <!-- <!– </a-space>–>--> |
| | | <!-- <!– </div>–>--> |
| | | <!-- </a-card>--> |
| | | <!-- </div>--> |
| | | <div |
| | | class="card-wrap" |
| | | v-for="(item, index) of agentList" |
| | |
| | | <img |
| | | :style="{ width: '100%' }" |
| | | alt="dessert" |
| | | src="https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a20012a2d4d5b9db43dfc6a01fe508c0.png~tplv-uwbnlip3yd-webp.webp" |
| | | :src="item.icon || 'https://p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a20012a2d4d5b9db43dfc6a01fe508c0.png~tplv-uwbnlip3yd-webp.webp'" |
| | | /> |
| | | </a-avatar> |
| | | <a-switch |
| | |
| | | <div style="position: absolute; bottom: 1rem; right: 1rem"> |
| | | <a-space> |
| | | <span v-show="!item.off"> |
| | | <editAgent |
| | | <agent-config |
| | | ref="editAgentKuai" |
| | | typeAngint="edit" |
| | | :formData="form" |
| | | @cancelModal="handleCancel" |
| | | ></editAgent> |
| | | :formData="item" |
| | | @queryList="queryList" |
| | | ></agent-config> |
| | | </span> |
| | | <a-popconfirm |
| | | :content="'确定删除吗'" |
| | | type="warning" |
| | | @ok="deleteItem(item)" |
| | | > |
| | | <a-button type="text" size="small"> |
| | | <a-button type="text" > |
| | | <template #icon> |
| | | <icon-delete /> |
| | | </template> |
| | |
| | | |
| | | <script lang="ts" setup> |
| | | import { ref, reactive, nextTick, onBeforeMount, onMounted, onBeforeUnmount } from "vue"; |
| | | import addAgent from '@/views/dmx/IntelligentAgent/components/addAgent.vue'; |
| | | import editAgent from '@/views/dmx/IntelligentAgent/components/editAgent.vue'; |
| | | import { kbdocumentrm, queryKbList } from '@/api/kbList'; |
| | | import { Message } from '@arco-design/web-vue'; |
| | | import { deletedialog, querydialogList } from '@/api/Agent'; |
| | | import useLoading from '@/hooks/loading'; |
| | | const { loading, setLoading } = useLoading(true); |
| | | import EventBus from '@/utils/EventBus'; |
| | | import AgentConfig from "@/views/dmx/IntelligentAgent/components/agentConfig.vue"; |
| | | |
| | | let count = 5; |
| | | const activeKey = ref(1); |
| | |
| | | }; |
| | | const handleAdd = () => { |
| | | addAgents.value.handleClick(); |
| | | }; |
| | | const handleDelete = (key: any) => { |
| | | data.value = data.value.filter((item) => item.key !== key); |
| | | }; |
| | | |
| | | const visible = ref(false); |
| | |
| | | @change="search" |
| | | /> |
| | | <!--新建--> |
| | | <add :kbobj="kbobj" @changeFetchData="changeFetchData"/> |
| | | <span v-if="tabs.length > 0"> |
| | | <add :kbobj="kbobj" @changeFetchData="changeFetchData"/> |
| | | </span> |
| | | </a-col> |
| | | </a-row> |
| | | </a-form> |