Commit 76d094c0 authored by shirlyn.guo's avatar shirlyn.guo 👌🏻

feat: 记忆变量

parent 287eb221
...@@ -38,6 +38,7 @@ common_module: ...@@ -38,6 +38,7 @@ common_module:
copy_success_message: '复制成功' copy_success_message: '复制成功'
delete_success_message: '删除成功' delete_success_message: '删除成功'
save_success_message: '保存成功' save_success_message: '保存成功'
save_fail_message: '保存失败'
edit_success_message: '编辑成功' edit_success_message: '编辑成功'
publish_success_message: '发布成功' publish_success_message: '发布成功'
clear_success_message: '清空成功' clear_success_message: '清空成功'
...@@ -61,6 +62,7 @@ common_module: ...@@ -61,6 +62,7 @@ common_module:
collect_successfully: '收藏成功' collect_successfully: '收藏成功'
collect_unsubscribed: '已取消收藏' collect_unsubscribed: '已取消收藏'
cancel: '取消' cancel: '取消'
preservation: '保存'
dialogue_module: dialogue_module:
continue_question_message: '你可以继续提问' continue_question_message: '你可以继续提问'
...@@ -223,6 +225,38 @@ personal_space_module: ...@@ -223,6 +225,38 @@ personal_space_module:
continuous_question_default_desc: '根据用户最近一轮对话,在回复后自动提供3个提问建议。' continuous_question_default_desc: '根据用户最近一轮对话,在回复后自动提供3个提问建议。'
continuous_question_close: '关闭' continuous_question_close: '关闭'
continuous_question_close_desc: '在每轮回复后,不会提供用户任何提问建议' continuous_question_close_desc: '在每轮回复后,不会提供用户任何提问建议'
memory: '记忆'
add_memory_variable: '添加记忆变量'
memory_variable: '记忆变量'
memory_message:
'开发者可根据应用设定记忆变量,应用用户在对话过程中可以录入变量内容,每个变量支持存储一维、单个数据。
在对话过程中,应用将依据存储的变量值进行答复。下面以「旅游助手」为例:'
memory_variable_message: '记录聊天对话中的一维、单个的应用信息或用户信息,能让智能体回答更加个性化。'
memory_variable_action_edit: '编辑'
memory_variable_action_copy: '复制名称'
variable_name: '变量名称'
variable_value: '变量值'
memory_variable_modal:
edit_memory_variable: '编辑记忆变量'
memory_variable_message_tip: '删除变量或修改变量名称/描述,应用更新发布后会导致应用用户对应的变量数据被删除或重置为默认值,请谨慎操作'
memory_variable_table_name: '名称'
memory_variable_table_name_tip: '填写内容'
memory_variable_table_name_content: '1.仅支持英文、中文'
memory_variable_table_name_length: '2.长度50字以内'
memory_variable_table_default_value: '默认值'
default_value_tip: '开发者可以为应用用户预先设定默认值'
default_value_tip_example: '实例:北京'
memory_variable_table_action: '操作'
default_value_placeholder: '请输入'
name_placeholder: '请输入名称'
add_variable: '新增变量'
memory_variable_rules:
name_not_null: '请输入名称'
name_length: '名称长度不能超过50个字'
name_supports: '仅支持英文和中文'
name_not_duplicated: '名称不能重复'
preview: '预览与调试' preview: '预览与调试'
......
...@@ -38,6 +38,7 @@ common_module: ...@@ -38,6 +38,7 @@ common_module:
copy_success_message: '複製成功' copy_success_message: '複製成功'
delete_success_message: '刪除成功' delete_success_message: '刪除成功'
save_success_message: '保存成功' save_success_message: '保存成功'
save_fail_message: '保存失敗'
edit_success_message: '編輯成功' edit_success_message: '編輯成功'
publish_success_message: '發佈成功' publish_success_message: '發佈成功'
clear_success_message: '清空成功' clear_success_message: '清空成功'
...@@ -61,6 +62,7 @@ common_module: ...@@ -61,6 +62,7 @@ common_module:
collect_successfully: '收藏成功' collect_successfully: '收藏成功'
collect_unsubscribed: '已取消收藏' collect_unsubscribed: '已取消收藏'
cancel: '取消' cancel: '取消'
preservation: '保存'
dialogue_module: dialogue_module:
continue_question_message: '你可以繼續提問' continue_question_message: '你可以繼續提問'
...@@ -223,6 +225,38 @@ personal_space_module: ...@@ -223,6 +225,38 @@ personal_space_module:
continuous_question_default_desc: '根據用戶最近一輪對話,在回覆後自動提供3個提問建議。' continuous_question_default_desc: '根據用戶最近一輪對話,在回覆後自動提供3個提問建議。'
continuous_question_close: '關閉' continuous_question_close: '關閉'
continuous_question_close_desc: '在每輪迴復後,不會提供用戶任何提問建議' continuous_question_close_desc: '在每輪迴復後,不會提供用戶任何提問建議'
memory: '記憶'
add_memory_variable: '添加記憶變數'
memory_variable: '記憶變量'
memory_message:
'开发者可根据应用设定记忆变量,应用用户在对话过程中可以录入变量内容,每个变量支持存储一维、单个数据。
在对话过程中,应用将依据存储的变量值进行答复。下面以「旅游助手」为例:'
memory_variable_message: '记录聊天对话中的一维、单个的应用信息或用户信息,能让智能体回答更加个性化。'
memory_variable_action_edit: '編輯'
memory_variable_action_copy: '複製名稱'
variable_name: '变量名稱'
variable_value: '变量值'
memory_variable_modal:
edit_memory_variable: '編輯記憶變數'
memory_variable_message_tip: '删除變數或修改變數名稱/描述,應用更新發佈後會導致應用用戶對應的變數數據被删除或重置為預設值,請謹慎操作'
memory_variable_table_name: '名稱'
memory_variable_table_name_tip: '填写内容'
memory_variable_table_name_content: '1.僅支持英文、中文'
memory_variable_table_name_length: '2.長度50字以内'
memory_variable_table_default_value: '預設值'
default_value_tip: '開發者可以為應用用戶預先設定預設值'
default_value_tip_example: '實例:北京'
memory_variable_table_action: '操作'
default_value_placeholder: '請輸入'
name_placeholder: '請輸入名稱'
add_variable: '新增變數'
memory_variable_rules:
name_not_null: '請求輸入名稱'
name_length: '名字長度不能超過50個字'
name_supports: '僅支持英文和中文'
name_not_duplicated: '名稱不能重複'
preview: '預覽與調試' preview: '預覽與調試'
......
export interface VariableStructureItem {
key: string
variableDefault: string | null
}
export interface PersonalAppConfigState { export interface PersonalAppConfigState {
baseInfo: { baseInfo: {
agentId: string //应用ID agentId: string //应用ID
...@@ -13,7 +18,7 @@ export interface PersonalAppConfigState { ...@@ -13,7 +18,7 @@ export interface PersonalAppConfigState {
continuousQuestionStatus: 'default' | 'close' //追问状态 continuousQuestionStatus: 'default' | 'close' //追问状态
continuousQuestionSystem: string // 追问提示词 customizable时必填 continuousQuestionSystem: string // 追问提示词 customizable时必填
continuousQuestionTurn: number // 追问轮次 1-5 customizable时必填 continuousQuestionTurn: number // 追问轮次 1-5 customizable时必填
variableStructure: object[] variableStructure: VariableStructureItem[]
} }
knowledgeConfig: { knowledgeConfig: {
knowledgeIds: string[] //知识库ID knowledgeIds: string[] //知识库ID
......
...@@ -6,6 +6,8 @@ import MessageList from './message-list.vue' ...@@ -6,6 +6,8 @@ import MessageList from './message-list.vue'
import FooterInput from './footer-input.vue' import FooterInput from './footer-input.vue'
import { fetchCreateContinueQuestions } from '@/apis/agent-application' import { fetchCreateContinueQuestions } from '@/apis/agent-application'
import { usePersonalAppConfigStore } from '@/store/modules/personal-app-config' import { usePersonalAppConfigStore } from '@/store/modules/personal-app-config'
import { Brain, Down } from '@icon-park/vue-next'
import MemoryPreviewModal from './memory-preview-modal.vue'
const { t } = useI18n() const { t } = useI18n()
...@@ -19,6 +21,7 @@ const messageList = ref<ConversationMessageItem[]>([]) ...@@ -19,6 +21,7 @@ const messageList = ref<ConversationMessageItem[]>([])
const continuousQuestionStatus = ref<'default' | 'close'>(personalAppConfigStore.commConfig.continuousQuestionStatus) const continuousQuestionStatus = ref<'default' | 'close'>(personalAppConfigStore.commConfig.continuousQuestionStatus)
const continuousQuestionList = ref<string[]>([]) const continuousQuestionList = ref<string[]>([])
const isShowMemoryPreviewModal = ref(false)
function handleAddMessageItem(messageItem: ConversationMessageItem) { function handleAddMessageItem(messageItem: ConversationMessageItem) {
messageList.value.push(messageItem) messageList.value.push(messageItem)
...@@ -67,13 +70,51 @@ function handleUpdateContinueQuestionStatus(status: 'default' | 'close') { ...@@ -67,13 +70,51 @@ function handleUpdateContinueQuestionStatus(status: 'default' | 'close') {
continuousQuestionStatus.value = status continuousQuestionStatus.value = status
continuousQuestionList.value = [] continuousQuestionList.value = []
} }
function handleMemoryVariable() {
isShowMemoryPreviewModal.value = true
}
</script> </script>
<template> <template>
<div class="flex h-full min-w-[300px] flex-1 flex-col overflow-hidden bg-[#f2f5f9]"> <div class="flex h-full min-w-[300px] flex-1 flex-col overflow-hidden bg-[#f2f5f9]">
<p class="mb-[18px] px-5 py-[18px] text-base"> <div class="flex justify-between">
{{ t('personal_space_module.agent_module.agent_setting_module.agent_config_module.preview') }} <p class="mb-[18px] px-5 py-[18px] text-base">
</p> {{ t('personal_space_module.agent_module.agent_setting_module.agent_config_module.preview') }}
</p>
<div
v-show="personalAppConfigStore.commConfig.variableStructure.length !== 0"
class="memory-content cursor-pointer"
>
<n-popover
placement="bottom"
arrow-wrapper-class="memory-content"
trigger="hover"
class="p-[4px]! top-[-25px]"
:show-arrow="false"
>
<template #trigger>
<div class="mb-[18px] flex items-center justify-center px-5 py-[18px] text-[14px]">
<Brain theme="outline" size="16" fill="#333" />
<div class="mx-[4px]">
{{ t('personal_space_module.agent_module.agent_setting_module.agent_config_module.memory') }}
</div>
<Down theme="outline" size="16" fill="#333" class="inline" />
</div>
</template>
<div>
<div
v-show="personalAppConfigStore.commConfig.variableStructure !== null"
class="cursor-pointer px-[8px] py-[5px] hover:bg-[#f2f5f9]"
@click="handleMemoryVariable"
>
{{ t('personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable') }}
</div>
</div>
</n-popover>
</div>
</div>
<div class="flex w-full flex-1 overflow-hidden"> <div class="flex w-full flex-1 overflow-hidden">
<div v-show="messageList.length === 0" class="flex w-full"> <div v-show="messageList.length === 0" class="flex w-full">
...@@ -102,6 +143,8 @@ function handleUpdateContinueQuestionStatus(status: 'default' | 'close') { ...@@ -102,6 +143,8 @@ function handleUpdateContinueQuestionStatus(status: 'default' | 'close') {
@create-continue-questions="handleCreateContinueQuestions" @create-continue-questions="handleCreateContinueQuestions"
@update-continuous-question-status="handleUpdateContinueQuestionStatus" @update-continuous-question-status="handleUpdateContinueQuestionStatus"
/> />
<MemoryPreviewModal v-model="isShowMemoryPreviewModal" />
</div> </div>
</template> </template>
......
...@@ -5,6 +5,7 @@ import { FormInst, InputInst, SelectOption } from 'naive-ui' ...@@ -5,6 +5,7 @@ import { FormInst, InputInst, SelectOption } from 'naive-ui'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useThrottleFn } from '@vueuse/core' import { useThrottleFn } from '@vueuse/core'
import CustomIcon from '@/components/custom-icon/custom-icon.vue' import CustomIcon from '@/components/custom-icon/custom-icon.vue'
import { Plus, Help, MoreOne, Edit, Copy, ReduceOne, Down, People, RightOne } from '@icon-park/vue-next'
import UploadImage from '@/components/upload-image/upload-image.vue' import UploadImage from '@/components/upload-image/upload-image.vue'
import AutoConfigModal from './auto-config-modal.vue' import AutoConfigModal from './auto-config-modal.vue'
import OptimizeSystemModal from './optimize-system-modal.vue' import OptimizeSystemModal from './optimize-system-modal.vue'
...@@ -22,6 +23,9 @@ import { ...@@ -22,6 +23,9 @@ import {
} from '@/apis/agent-application' } from '@/apis/agent-application'
import { fetchCustomEventSource } from '@/composables/useEventSource' import { fetchCustomEventSource } from '@/composables/useEventSource'
import { DiversityModeItem, diversityModeList } from '../app-setting-config' import { DiversityModeItem, diversityModeList } from '../app-setting-config'
import MemoryVariableModal from './memory-variable-modal.vue'
import type { MemoryVariableForm } from './memory-variable-modal.vue'
import { copyToClip } from '@/utils/copy'
const { t } = useI18n() const { t } = useI18n()
...@@ -75,9 +79,11 @@ const isShowOptimizeAgentSystemModal = ref(false) // 是否显示优化角色指 ...@@ -75,9 +79,11 @@ const isShowOptimizeAgentSystemModal = ref(false) // 是否显示优化角色指
const generateAgentAvatarLoading = ref(false) // 是否正在生成图片 const generateAgentAvatarLoading = ref(false) // 是否正在生成图片
const generatePreambleLoading = ref(false) // 是否正在生成开场白 const generatePreambleLoading = ref(false) // 是否正在生成开场白
const generateFeaturedQuestionsLoading = ref(false) // 是否正在生成推荐词 const generateFeaturedQuestionsLoading = ref(false) // 是否正在生成推荐词
const isShowMemoryVariableModal = ref(false) //是否显示记忆变量弹窗
const personalAppFormRef = ref<FormInst | null>(null) const personalAppFormRef = ref<FormInst | null>(null)
const agentSystemInputRef = ref<InputInst | null>(null) const agentSystemInputRef = ref<InputInst | null>(null)
const memoryVariableModal = ref<InstanceType<typeof MemoryVariableModal> | null>(null)
const personalAppRules = { const personalAppRules = {
baseInfo: { baseInfo: {
...@@ -461,6 +467,46 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) { ...@@ -461,6 +467,46 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) {
personalAppConfig.value.commModelConfig.temperature = temperature personalAppConfig.value.commModelConfig.temperature = temperature
personalAppConfig.value.commModelConfig.communicationTurn = communicationTurn personalAppConfig.value.commModelConfig.communicationTurn = communicationTurn
} }
function handleShowMemoryVariableModal() {
isShowMemoryVariableModal.value = true
}
function handleDeleteMemoryVariableItem(memoryVariable: object) {
window.$dialog.warning({
title: '删除提示',
content: '删除后不可撤销。如应用已发布,更新发布后该应用的用户无法使用该记忆变量,是否继续?',
positiveText: '确定',
negativeText: '取消',
onPositiveClick: () => {
personalAppConfigStore.updatePersonalAppConfigState({
commConfig: {
...personalAppConfigStore.commConfig,
variableStructure: personalAppConfigStore.commConfig.variableStructure.filter(
(variable) => variable !== memoryVariable,
),
},
})
window.$message.success('删除成功')
},
onNegativeClick: () => {
window.$message.success('已取消')
},
})
}
function handleAddMemoryVariable() {
isShowMemoryVariableModal.value = true
if (memoryVariableModal.value) {
memoryVariableModal.value.handleAddMemoryVariableItem()
}
}
function handleCopyMemoryVariableName(memoryVariableItem: MemoryVariableForm) {
copyToClip(memoryVariableItem.key)
window.$message.success('成功复制名称')
}
</script> </script>
<template> <template>
...@@ -494,7 +540,7 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) { ...@@ -494,7 +540,7 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) {
<span class="line-clamp-1 w-[100px] text-xs text-[#5c5f66]"> <span class="line-clamp-1 w-[100px] text-xs text-[#5c5f66]">
{{ personalAppConfig.commModelConfig.largeModel }} {{ personalAppConfig.commModelConfig.largeModel }}
</span> </span>
<CustomIcon icon="mingcute:down-line" class="ml-1.5 text-base outline-none" /> <Down theme="outline" size="16" fill="#333" class="ml-1.5 text-base outline-none" />
</div> </div>
</template> </template>
<div class="mb-2 mt-[6px] flex items-center"> <div class="mb-2 mt-[6px] flex items-center">
...@@ -548,8 +594,11 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) { ...@@ -548,8 +594,11 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) {
</span> </span>
<NPopover trigger="hover"> <NPopover trigger="hover">
<template #trigger> <template #trigger>
<CustomIcon <Help
icon="mingcute:question-line" theme="outline"
size="15"
fill="#333"
:stroke-width="2"
class="ml-1 cursor-pointer text-base text-[#999] outline-none" class="ml-1 cursor-pointer text-base text-[#999] outline-none"
/> />
</template> </template>
...@@ -594,8 +643,11 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) { ...@@ -594,8 +643,11 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) {
</span> </span>
<NPopover trigger="hover"> <NPopover trigger="hover">
<template #trigger> <template #trigger>
<CustomIcon <Help
icon="mingcute:question-line" theme="outline"
size="15"
fill="#333"
:stroke-width="2"
class="ml-1 cursor-pointer text-base text-[#999] outline-none" class="ml-1 cursor-pointer text-base text-[#999] outline-none"
/> />
</template> </template>
...@@ -642,8 +694,11 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) { ...@@ -642,8 +694,11 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) {
</span> </span>
<NPopover trigger="hover"> <NPopover trigger="hover">
<template #trigger> <template #trigger>
<CustomIcon <Help
icon="mingcute:question-line" theme="outline"
size="15"
fill="#333"
:stroke-width="2"
class="ml-1 cursor-pointer text-base text-[#999] outline-none" class="ml-1 cursor-pointer text-base text-[#999] outline-none"
/> />
</template> </template>
...@@ -685,7 +740,7 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) { ...@@ -685,7 +740,7 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) {
<div class="flex h-[calc(100vh-56px-56px)]"> <div class="flex h-[calc(100vh-56px-56px)]">
<div class="flex h-full flex-1 flex-col overflow-auto border-r border-[#e8e9eb] py-4"> <div class="flex h-full flex-1 flex-col overflow-auto border-r border-[#e8e9eb] py-4">
<div class="mb-1 flex h-6 items-center px-5 leading-6"> <div class="mb-1 flex h-6 items-center px-5 leading-6">
<CustomIcon icon="mdi:user" class="mr-1.5 text-lg" /> <People theme="multi-color" size="16" :fill="['#333', '#333', '#333', '#333']" class="mr-1.5 text-lg" />
<span> <span>
{{ t('personal_space_module.agent_module.agent_setting_module.agent_config_module.agent_setting') }} {{ t('personal_space_module.agent_module.agent_setting_module.agent_config_module.agent_setting') }}
</span> </span>
...@@ -693,7 +748,7 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) { ...@@ -693,7 +748,7 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) {
<NCollapse :default-expanded-names="['1']" class="px-5"> <NCollapse :default-expanded-names="['1']" class="px-5">
<template #arrow> <template #arrow>
<CustomIcon icon="gravity-ui:caret-right" /> <RightOne theme="multi-color" size="17" :fill="['#333', '#333', '#333', '#333']" />
</template> </template>
<NCollapseItem <NCollapseItem
:title="t('personal_space_module.agent_module.agent_setting_module.agent_config_module.base_info')" :title="t('personal_space_module.agent_module.agent_setting_module.agent_config_module.base_info')"
...@@ -791,8 +846,11 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) { ...@@ -791,8 +846,11 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) {
</span> </span>
<NPopover style="width: 520px" trigger="hover"> <NPopover style="width: 520px" trigger="hover">
<template #trigger> <template #trigger>
<CustomIcon <Help
icon="mingcute:question-line" theme="outline"
size="15"
fill="#333"
:stroke-width="2"
class="ml-1 cursor-pointer text-base text-[#999] outline-none" class="ml-1 cursor-pointer text-base text-[#999] outline-none"
/> />
</template> </template>
...@@ -893,7 +951,7 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) { ...@@ -893,7 +951,7 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) {
</h2> </h2>
<NCollapse :trigger-areas="['main', 'arrow']"> <NCollapse :trigger-areas="['main', 'arrow']">
<template #arrow> <template #arrow>
<CustomIcon icon="gravity-ui:caret-right" /> <RightOne theme="multi-color" size="17" :fill="['#333', '#333', '#333', '#333']" />
</template> </template>
<NCollapseItem <NCollapseItem
...@@ -911,6 +969,134 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) { ...@@ -911,6 +969,134 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) {
</div> </div>
</section> </section>
<section class="border-b border-[#e8e9eb] px-5">
<div class="pt-4">
<h2 class="my-3 text-[#84868c]">
{{ t('personal_space_module.agent_module.agent_setting_module.agent_config_module.memory') }}
</h2>
<NCollapse
:expanded-names="commConfigExpandedNames"
:trigger-areas="['main', 'arrow']"
@update:expanded-names="handleUpdateCommConfigExpandedNames"
>
<template #arrow>
<RightOne theme="multi-color" size="17" :fill="['#333', '#333', '#333', '#333']" />
</template>
<NCollapseItem name="preamble" class="my-[13px]!">
<template #header>
<span class="w-[60px]">{{
t('personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable')
}}</span>
<n-popover trigger="hover" placement="top-start" class="p-[12px]! left-[-120px]!" :show-arrow="false">
<template #trigger>
<Help theme="outline" size="15" fill="#333" :stroke-width="2" class="mt-[2px]" />
</template>
<div class="w-[650px] text-[14px]">
<div class="m-w-[100%] mb-[16px] mt-[0px] leading-[22px]">
{{
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_message',
)
}}
</div>
<div>
<img src="@/assets/images/memory-variableLabels.png" width="650" height="206" />
</div>
</div>
</n-popover>
</template>
<template #header-extra>
<NTooltip trigger="hover">
<template #trigger>
<Plus
theme="outline"
size="22"
:stroke-width="2"
class="text-theme-color cursor-pointer"
@click="handleAddMemoryVariable"
/>
</template>
{{
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.add_memory_variable',
)
}}
</NTooltip>
</template>
<div class="mb-[16px] text-xs text-[#84868c]">
{{
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable_message',
)
}}
</div>
<div
v-show="personalAppConfigStore.commConfig.variableStructure.length !== 0"
class="flex flex-1 flex-wrap items-center gap-[12px] overflow-hidden"
>
<div
v-for="(memoryVariableItem, index) in personalAppConfigStore.commConfig.variableStructure"
:key="index"
class="font-400 line-height-[20px] flex cursor-pointer items-center rounded-[4px] bg-[#f2f5f9] py-[2px] pl-[8px] text-[12px] hover:bg-[#e3e8f0]"
@click="handleShowMemoryVariableModal"
>
<n-popover v-if="memoryVariableItem.key.length > 8" trigger="hover" class="max-w-[250px]!">
<template #trigger>
<div class="max-w-[105px] truncate text-[#151b26]">{{ memoryVariableItem.key }}</div>
</template>
{{ memoryVariableItem.key }}
</n-popover>
<div v-else class="max-w-[105px] truncate text-[#151b26]">{{ memoryVariableItem.key }}</div>
<n-popover placement="bottom" trigger="hover" :show-arrow="false" class="p-[4px]!">
<template #trigger>
<MoreOne theme="outline" size="14" fill="#333" :stroke-width="2" class="mr-[4px] mt-[2px]" />
</template>
<div class="text-[12px]">
<div
class="flex h-[30px] w-[90px] cursor-pointer items-center justify-start px-[8px] py-[5px] hover:rounded-[4px] hover:bg-[#f2f5f9]"
@click="handleShowMemoryVariableModal"
>
<Edit theme="outline" size="16" fill="#333" :stroke-width="2" /><span class="ml-[4px]">
{{
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable_action_edit',
)
}}
</span>
</div>
<div
class="flex h-[30px] w-[90px] cursor-pointer items-center justify-start px-[8px] py-[5px] hover:rounded-[4px] hover:bg-[#f2f5f9]"
@click="handleCopyMemoryVariableName(memoryVariableItem)"
>
<Copy theme="outline" size="16" fill="#333" :stroke-width="2" />
<span class="ml-[4px]">
{{
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable_action_copy',
)
}}
</span>
</div>
<n-space>
<div
class="flex h-[30px] w-[90px] cursor-pointer items-center justify-start px-[8px] py-[5px] hover:rounded-[4px] hover:bg-[#f2f5f9]"
@click="handleDeleteMemoryVariableItem(memoryVariableItem)"
>
<ReduceOne theme="outline" size="16" fill="#333" :stroke-width="2" /><span class="ml-[4px]">
{{ t('common_module.delete') }}
</span>
</div>
</n-space>
</div>
</n-popover>
</div>
</div>
</NCollapseItem>
</NCollapse>
</div>
</section>
<section class="border-b border-[#e8e9eb] px-5"> <section class="border-b border-[#e8e9eb] px-5">
<div class="pt-4"> <div class="pt-4">
<h2 class="my-3 text-[#84868c]"> <h2 class="my-3 text-[#84868c]">
...@@ -922,7 +1108,7 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) { ...@@ -922,7 +1108,7 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) {
@update:expanded-names="handleUpdateCommConfigExpandedNames" @update:expanded-names="handleUpdateCommConfigExpandedNames"
> >
<template #arrow> <template #arrow>
<CustomIcon icon="gravity-ui:caret-right" /> <RightOne theme="multi-color" size="17" :fill="['#333', '#333', '#333', '#333']" />
</template> </template>
<NCollapseItem <NCollapseItem
:title="t('personal_space_module.agent_module.agent_setting_module.agent_config_module.preamble')" :title="t('personal_space_module.agent_module.agent_setting_module.agent_config_module.preamble')"
...@@ -1008,8 +1194,11 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) { ...@@ -1008,8 +1194,11 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) {
</span> </span>
<NPopover trigger="hover"> <NPopover trigger="hover">
<template #trigger> <template #trigger>
<CustomIcon <Help
icon="mingcute:question-line" theme="outline"
size="15"
fill="#333"
:stroke-width="2"
class="ml-1 cursor-pointer text-base text-[#999] outline-none" class="ml-1 cursor-pointer text-base text-[#999] outline-none"
/> />
</template> </template>
...@@ -1033,7 +1222,7 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) { ...@@ -1033,7 +1222,7 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) {
> >
<div class="text-theme-color flex cursor-pointer items-center justify-between text-xs"> <div class="text-theme-color flex cursor-pointer items-center justify-between text-xs">
<span> {{ continuousQuestionStatusText }}</span> <span> {{ continuousQuestionStatusText }}</span>
<CustomIcon icon="mingcute:down-line" class="ml-1 text-base" /> <Down theme="outline" size="16" class="text-theme-color ml-1 text-base" />
</div> </div>
</NPopselect> </NPopselect>
</template> </template>
...@@ -1109,6 +1298,8 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) { ...@@ -1109,6 +1298,8 @@ function handleDiversityModeChange(diversityModeItem: DiversityModeItem) {
" "
@confirm="handleSettingAgentSystem" @confirm="handleSettingAgentSystem"
/> />
<MemoryVariableModal ref="memoryVariableModal" v-model="isShowMemoryVariableModal" />
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
......
<script setup lang="ts">
import { usePersonalAppConfigStore } from '@/store/modules/personal-app-config'
import { Close } from '@icon-park/vue-next'
import { DataTableColumns } from 'naive-ui'
import { ref, watch } from 'vue'
import { MemoryVariableForm } from './memory-variable-modal.vue'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const memoryVariableColumns = createColumns()
const personalAppConfigStore = usePersonalAppConfigStore()
const memoryVariableData = ref([])
const isShowMemoryPreviewModal = defineModel<boolean>()
function createColumns(): DataTableColumns<MemoryVariableForm> {
return [
{
title: t('personal_space_module.agent_module.agent_setting_module.agent_config_module.variable_name'),
key: 'key',
width: 150,
},
{
title: t('personal_space_module.agent_module.agent_setting_module.agent_config_module.variable_value'),
key: 'variableDefault',
},
]
}
watch(
() => personalAppConfigStore.commConfig.variableStructure,
(newValue) => {
if (newValue !== null) {
memoryVariableData.value = JSON.parse(JSON.stringify(newValue))
}
},
{ immediate: true },
)
function handlePreviewModalClose() {
isShowMemoryPreviewModal.value = false
}
</script>
<template>
<n-modal v-model:show="isShowMemoryPreviewModal" class="h-auto max-h-[720px]" :mask-closable="false">
<div class="flex flex-col items-center justify-center">
<div class="max-h-[720px] w-[880px] rounded-lg bg-white p-[24px]">
<div class="flex items-center justify-end text-[20px]">
<Close theme="outline" size="18" fill="#00000073" class="cursor-pointer" @click="handlePreviewModalClose" />
</div>
<div class="">
<n-tabs type="line" animated>
<n-tab-pane
name="oasis"
:tab="t('personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable')"
>
<div class="flex max-h-[490px] justify-center overflow-y-hidden bg-[#f3f4fb]">
<n-data-table :columns="memoryVariableColumns" :max-height="440" :data="memoryVariableData" />
</div>
</n-tab-pane>
</n-tabs>
</div>
</div>
</div>
</n-modal>
</template>
<style lang="scss" scoped>
:deep(.n-tabs) {
.n-tabs-tab {
font-size: 20px;
}
.n-tabs-bar {
background-color: #fff;
}
.n-tabs-nav {
&.n-tabs-nav--line-type {
&.n-tabs-nav--top {
.n-tabs-nav-scroll-content {
border-bottom: none;
}
}
}
}
}
</style>
<script setup lang="ts">
import { Close, Attention, Plus, Help, Delete } from '@icon-park/vue-next'
import { nextTick, ref, shallowReadonly, watch } from 'vue'
import { usePersonalAppConfigStore } from '@/store/modules/personal-app-config'
import { FormInst, FormItemRule, FormRules } from 'naive-ui'
import { useI18n } from 'vue-i18n'
export interface MemoryVariableForm {
key: string
variableDefault: string | null
}
const { t } = useI18n()
const isShowMemoryVariableModal = defineModel<boolean>()
const personalAppConfigStore = usePersonalAppConfigStore()
const memoryVariableTable = ref<MemoryVariableForm[]>([{ key: '', variableDefault: '' }])
const memoryVariableFormRefs = ref<(FormInst | null)[]>([])
const memoryVariableInputRefs = ref<(HTMLInputElement | null)[]>([])
const memoryVariableFormRules = shallowReadonly<FormRules>({
key: {
trigger: ['input'],
validator: (_rule: FormItemRule, value: string) => {
const regex = /^[\u4e00-\u9fa5a-zA-Z]+$/
const valueIndex = memoryVariableTable.value.findIndex((item) => item.key === value)
const updatedMemoryVariableData =
valueIndex !== -1
? [...memoryVariableTable.value.slice(0, valueIndex), ...memoryVariableTable.value.slice(valueIndex + 1)]
: memoryVariableTable.value
const hasValue = updatedMemoryVariableData.some((item: { key: string }) => item.key === value)
if (!value) {
return new Error(
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable_modal.memory_variable_rules.name_not_null',
),
)
} else if (value.length > 50) {
return new Error(
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable_modal.memory_variable_rules.name_length',
),
)
} else if (!regex.test(value)) {
return new Error(
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable_modal.memory_variable_rules.name_supports',
),
)
} else if (hasValue) {
return new Error(
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable_modal.memory_variable_rules.name_not_duplicated',
),
)
}
return true
},
},
})
watch(
() => personalAppConfigStore.commConfig.variableStructure,
(newValue) => {
if (newValue !== null) {
memoryVariableTable.value = JSON.parse(JSON.stringify(newValue))
}
},
{ immediate: true },
)
function handlePreviewModalClose(refresh = false) {
isShowMemoryVariableModal.value = false
memoryVariableTable.value = refresh
? memoryVariableTable.value
: JSON.parse(JSON.stringify(personalAppConfigStore.commConfig.variableStructure))
memoryVariableTable.value = memoryVariableTable.value.filter((item) => item.key)
}
function handleMemoryVariableFormSave() {
const validationPromises = memoryVariableTable.value.map((_, index) => {
const formRef = memoryVariableFormRefs.value[index]
return new Promise<boolean>((resolve) => {
if (formRef) {
formRef.validate((errors: any) => {
resolve(!errors)
})
} else {
resolve(false)
}
})
})
Promise.all(validationPromises).then((results) => {
const isAllValid = results.every((result) => result)
if (isAllValid) {
personalAppConfigStore.commConfig.variableStructure = memoryVariableTable.value
handlePreviewModalClose(true)
window.$message.success(t('common_module.save_success_message'))
} else {
window.$message.error(t('common_module.save_fail_message'))
}
})
}
function handleAddMemoryVariableItem() {
const newVariable = { key: '', variableDefault: '' }
memoryVariableTable.value.push(newVariable)
nextTick(() => {
const newIndex = memoryVariableTable.value.length - 1
const input = memoryVariableInputRefs.value[newIndex]
if (input) {
input.focus()
}
})
}
function handleDeleteMemoryVariableRow(rowItem: MemoryVariableForm) {
const index = memoryVariableTable.value.findIndex((item) => item.key === rowItem.key)
if (index !== -1) {
memoryVariableTable.value.splice(index, 1)
}
}
defineExpose({
handleAddMemoryVariableItem,
})
</script>
<template>
<n-modal
v-model:show="isShowMemoryVariableModal"
class="h-auto max-h-[720px]"
:mask-closable="false"
:auto-focus="false"
>
<div class="flex flex-col items-center justify-center">
<div class="max-h-[720px] w-[820px] rounded-lg bg-white p-[24px]">
<div class="flex items-center justify-between text-[20px]">
<span>
{{
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable_modal.edit_memory_variable',
)
}}</span
>
<Close theme="outline" size="18" fill="#00000073" class="cursor-pointer" @click="handlePreviewModalClose()" />
</div>
<div
class="mb-[12px] mt-[16px] flex items-center justify-center rounded-[4px] bg-[#FFF4E6] px-[15px] pb-[3px] pt-[4px]"
>
<div class="mr-[5px] h-[14px] w-[14px]">
<Attention
theme="multi-color"
size="14"
:fill="['#ff9326', '#ff9326', '#FFF', '#43CCF8']"
:stroke-width="2"
/>
</div>
<div class="text-[14px] text-[#151B26]">
{{
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable_modal.memory_variable_message_tip',
)
}}
</div>
</div>
<div>
<n-scrollbar style="max-height: 490px; overflow: hidden">
<div class="flex justify-center">
<table class="w-full">
<thead class="sticky top-[0px] z-20 text-[#5c5f66]">
<tr class="bg-[#f2f5f9]">
<th class="px-[24px] py-[10px] font-normal">
<div class="flex">
<div>
{{
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable_modal.memory_variable_table_name',
)
}}
</div>
<span class="ml-[3px] text-[#ff6966]">*</span>
</div>
</th>
<th class="px-[24px] py-[10px] font-normal">
<div class="flex items-center">
<div class="mr-[2px]" style="margin-right: 7px">
{{
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable_modal.memory_variable_table_default_value',
)
}}
</div>
<n-popover trigger="hover" class="p-[12px]!">
<template #trigger>
<Help theme="outline" size="15" fill="#333" :stroke-width="2" class="mt-[2px]" />
</template>
<div class="mb-[8px] w-[226px]">
{{
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable_modal.default_value_tip',
)
}}
</div>
<div>
<span class="w-[86px] rounded-[4px] bg-[#f2f5f9] px-[8px] py-[4px]">{{
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable_modal.default_value_tip_example',
)
}}</span>
</div>
</n-popover>
</div>
</th>
<th class="px-[12px] py-[10px] font-normal">
{{
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable_modal.memory_variable_table_action',
)
}}
</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in memoryVariableTable" :key="index">
<td class="pl-[12px]">
<n-form
:ref="(el: any) => (memoryVariableFormRefs[index] = el)"
label-width="auto"
:model="item"
:rules="memoryVariableFormRules"
:show-label="false"
>
<n-form-item path="key" :show-label="false">
<n-popover trigger="click" placement="right" class="p-[12px]!">
<template #trigger>
<n-input
:ref="(el: HTMLInputElement) => (memoryVariableInputRefs[index] = el)"
v-model:value="item.key"
:placeholder="
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable_modal.name_placeholder',
)
"
maxlength="50"
show-count
/>
</template>
<div class="w-[226px]">
{{
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable_modal.memory_variable_table_name_tip',
)
}}
</div>
<div>
{{
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable_modal.memory_variable_table_name_content',
)
}}
</div>
<div>
{{
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable_modal.memory_variable_table_name_length',
)
}}
</div>
</n-popover>
</n-form-item>
</n-form>
</td>
<td class="pl-[12px]">
<n-form-item path="variableDefault" :show-label="false">
<n-input
v-model:value="item.variableDefault"
type="text"
:placeholder="
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable_modal.default_value_placeholder',
)
"
:maxlength="400"
show-count
/>
</n-form-item>
</td>
<td class="ml-[15px] mt-[10px] flex pl-[12px] pt-[10px]">
<n-tooltip trigger="hover">
<template #trigger>
<Delete
theme="outline"
size="15"
fill="#333"
:stroke-width="2"
class="mt-[2px] cursor-pointer"
@click="handleDeleteMemoryVariableRow(item)"
/>
</template>
{{ t('common_module.delete') }}
</n-tooltip>
</td>
</tr>
</tbody>
</table>
</div>
</n-scrollbar>
<div class="text-theme-color mt-[16px] flex w-[78px] cursor-pointer" @click="handleAddMemoryVariableItem">
<Plus theme="outline" size="22" :stroke-width="2" class="text-theme-color" />
<span>{{
t(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.memory_variable_modal.add_variable',
)
}}</span>
</div>
<div class="mt-[24px] flex justify-end">
<button
class="hover:text-theme-color hover:border-theme-color !mr-[12px] box-content !h-[38px] !w-[74px] cursor-pointer rounded-[6px] border-[1px] border-solid border-[#dde3f0] px-[10px] outline-none transition-all duration-300 hover:border-[theme-color]"
@click="handlePreviewModalClose()"
>
{{ t('common_module.cancel_btn_text') }}
</button>
<button
class="bg-theme-color !box-content !h-[38px] !w-[74px] cursor-pointer rounded-[6px] border-[1px] border-solid border-[#dde3f0] bg-[te] px-[10px] text-[#ffffff] transition-all duration-300 hover:bg-[#528EFF]"
@click="handleMemoryVariableFormSave()"
>
{{ t('common_module.preservation') }}
</button>
</div>
</div>
</div>
</div>
</n-modal>
</template>
<style lang="scss" scoped>
tbody tr:first-child td {
padding-top: 10px;
}
</style>
...@@ -39,6 +39,7 @@ declare namespace I18n { ...@@ -39,6 +39,7 @@ declare namespace I18n {
copy_success_message: string copy_success_message: string
delete_success_message: string delete_success_message: string
save_success_message: string save_success_message: string
save_fail_message: string
edit_success_message: string edit_success_message: string
publish_success_message: string publish_success_message: string
clear_success_message: string clear_success_message: string
...@@ -62,6 +63,7 @@ declare namespace I18n { ...@@ -62,6 +63,7 @@ declare namespace I18n {
collect_successfully: string collect_successfully: string
collect_unsubscribed: string collect_unsubscribed: string
cancel: string cancel: string
preservation: string
dialogue_module: { dialogue_module: {
continue_question_message: string continue_question_message: string
...@@ -225,6 +227,38 @@ declare namespace I18n { ...@@ -225,6 +227,38 @@ declare namespace I18n {
continuous_question_default_desc: string continuous_question_default_desc: string
continuous_question_close: string continuous_question_close: string
continuous_question_close_desc: string continuous_question_close_desc: string
memory: string
add_memory_variable: string
memory_variable: string
memory_message: string
memory_variable_message: string
memory_variable_action_edit: string
memory_variable_action_copy: string
variable_name: string
variable_value: string
memory_variable_modal: {
edit_memory_variable: string
memory_variable_message_tip: string
memory_variable_table_name: string
memory_variable_table_name_tip: string
memory_variable_table_name_content: string
memory_variable_table_name_length: string
memory_variable_table_default_value: string
default_value_tip: string
default_value_tip_example: string
memory_variable_table_action: string
default_value_placeholder: string
name_placeholder: string
add_variable: string
memory_variable_rules: {
name_not_null: string
name_length: string
name_supports: string
name_not_duplicated: string
}
}
preview: string preview: string
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment