Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
P
poc-fe
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
poc
poc-fe
Commits
25671c81
Commit
25671c81
authored
Nov 01, 2024
by
nick zheng
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'beta' into 'master'
feat: 多模型测试 See merge request
!31
parents
eb581b8c
32eb29f4
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
1378 additions
and
4 deletions
+1378
-4
index.html
index.html
+1
-1
empty-model.png
src/assets/images/empty-model.png
+0
-0
agent-setting-data.ts
src/data/agent-setting-data.ts
+38
-0
zh-cn.yaml
src/locales/langs/zh-cn.yaml
+20
-0
zh-hk.yaml
src/locales/langs/zh-hk.yaml
+20
-0
dialogue.ts
src/router/modules/dialogue.ts
+15
-0
footer-operation.vue
...iews/multi-model-dialogue/components/footer-operation.vue
+212
-0
message-bubble-loading.vue
...ulti-model-dialogue/components/message-bubble-loading.vue
+50
-0
message-item.vue
src/views/multi-model-dialogue/components/message-item.vue
+71
-0
message-list.vue
src/views/multi-model-dialogue/components/message-list.vue
+36
-0
model-dialogue-item.vue
...s/multi-model-dialogue/components/model-dialogue-item.vue
+177
-0
model-setting.vue
src/views/multi-model-dialogue/components/model-setting.vue
+244
-0
page-header.vue
src/views/multi-model-dialogue/components/page-header.vue
+73
-0
multi-model-dialogue.vue
src/views/multi-model-dialogue/multi-model-dialogue.vue
+339
-0
types.d.ts
src/views/multi-model-dialogue/types.d.ts
+34
-0
app-preview.vue
...nal-space/personal-app-setting/components/app-preview.vue
+26
-3
locales.d.ts
types/locales.d.ts
+21
-0
uno.config.ts
uno.config.ts
+1
-0
No files found.
index.html
View file @
25671c81
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
name=
"viewport"
name=
"viewport"
content=
"width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
content=
"width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
/>
<link
rel=
"stylesheet"
href=
"//at.alicdn.com/t/c/font_4711453_
vrea727r3s
.css"
/>
<link
rel=
"stylesheet"
href=
"//at.alicdn.com/t/c/font_4711453_
egfmzk2ywd
.css"
/>
<title>
SuperLink
</title>
<title>
SuperLink
</title>
</head>
</head>
...
...
src/assets/images/empty-model.png
0 → 100644
View file @
25671c81
977 Bytes
src/data/agent-setting-data.ts
0 → 100644
View file @
25671c81
export
interface
DiversityModeItem
{
label
:
string
value
:
string
topP
:
number
temperature
:
number
communicationTurn
:
number
}
export
const
diversityModeList
:
DiversityModeItem
[]
=
[
{
label
:
'common_module.accurate_mode'
,
value
:
'accurate'
,
topP
:
0.1
,
temperature
:
0.1
,
communicationTurn
:
3
,
},
{
label
:
'common_module.balance_mode'
,
value
:
'balance'
,
topP
:
0.7
,
temperature
:
0.5
,
communicationTurn
:
3
,
},
{
label
:
'common_module.creative_mode'
,
value
:
'creative'
,
topP
:
0.7
,
temperature
:
0.95
,
communicationTurn
:
3
,
},
{
label
:
'common_module.custom'
,
value
:
'custom'
,
topP
:
0.5
,
temperature
:
0.8
,
communicationTurn
:
3
,
},
]
src/locales/langs/zh-cn.yaml
View file @
25671c81
...
@@ -53,6 +53,11 @@ common_module:
...
@@ -53,6 +53,11 @@ common_module:
select_all
:
'
全选'
select_all
:
'
全选'
quit
:
'
退出'
quit
:
'
退出'
retry
:
'
重试'
retry
:
'
重试'
currently
:
'
当前'
multi_model_debug
:
'
多模型调试'
accurate_mode
:
'
精准模式'
balance_mode
:
'
平衡模式'
creative_mode
:
'
创意模式'
dialogue_module
:
dialogue_module
:
continue_question_message
:
'
你可以继续提问'
continue_question_message
:
'
你可以继续提问'
...
@@ -124,6 +129,7 @@ router_title_module:
...
@@ -124,6 +129,7 @@ router_title_module:
upload_knowledge_document
:
'
上传知识库文档'
upload_knowledge_document
:
'
上传知识库文档'
knowledge_document_list
:
'
知识库文档列表'
knowledge_document_list
:
'
知识库文档列表'
knowledge_document_detail
:
'
知识库文档详情'
knowledge_document_detail
:
'
知识库文档详情'
multi_model_dialogue
:
'
多模型调试'
personal_space_module
:
personal_space_module
:
title
:
'
个人空间'
title
:
'
个人空间'
...
@@ -297,3 +303,17 @@ share_agent_module:
...
@@ -297,3 +303,17 @@ share_agent_module:
create_agent_dialogue_title
:
'
温馨提示'
create_agent_dialogue_title
:
'
温馨提示'
create_agent_dialogue_content
:
'
为保证您的体验,请通过pc端访问'
create_agent_dialogue_content
:
'
为保证您的体验,请通过pc端访问'
create_agent_dialogue_positive_text
:
'
我知道啦'
create_agent_dialogue_positive_text
:
'
我知道啦'
multi_model_dialogue_module
:
not_find_agent
:
'
应用不存在'
add_model
:
'
增加模型'
quit_test
:
'
退出测试'
model_setting
:
'
模型设置'
agent_system
:
'
系统人设'
remove_dialogue
:
'
移除'
one_click_configuration
:
'
一键配置'
select_model
:
'
选择模型'
please_select_model
:
'
请选择模型'
please_select_model_first
:
'
请先选择模型'
replace_configuration_tip
:
'
是否将该模型的配置覆盖到原来的配置项上'
open_new_conversation
:
'
已开启新会话'
src/locales/langs/zh-hk.yaml
View file @
25671c81
...
@@ -53,6 +53,11 @@ common_module:
...
@@ -53,6 +53,11 @@ common_module:
select_all
:
'
全選'
select_all
:
'
全選'
quit
:
'
退出'
quit
:
'
退出'
retry
:
'
重試'
retry
:
'
重試'
currently
:
'
當前'
multi_model_debug
:
'
多模型調試'
accurate_mode
:
'
精準模式'
balance_mode
:
'
平衡模式'
creative_mode
:
'
創意模式'
dialogue_module
:
dialogue_module
:
continue_question_message
:
'
你可以繼續提問'
continue_question_message
:
'
你可以繼續提問'
...
@@ -124,6 +129,7 @@ router_title_module:
...
@@ -124,6 +129,7 @@ router_title_module:
upload_knowledge_document
:
'
上傳知識庫文檔'
upload_knowledge_document
:
'
上傳知識庫文檔'
knowledge_document_list
:
'
知識庫文檔列表'
knowledge_document_list
:
'
知識庫文檔列表'
knowledge_document_detail
:
'
知識庫文檔詳情'
knowledge_document_detail
:
'
知識庫文檔詳情'
multi_model_dialogue
:
'
多模型調試'
personal_space_module
:
personal_space_module
:
title
:
'
個人空間'
title
:
'
個人空間'
...
@@ -297,3 +303,17 @@ share_agent_module:
...
@@ -297,3 +303,17 @@ share_agent_module:
create_agent_dialogue_title
:
'
溫馨提示'
create_agent_dialogue_title
:
'
溫馨提示'
create_agent_dialogue_content
:
'
爲保證您的體驗,請通過pc端訪問'
create_agent_dialogue_content
:
'
爲保證您的體驗,請通過pc端訪問'
create_agent_dialogue_positive_text
:
'
我知道啦'
create_agent_dialogue_positive_text
:
'
我知道啦'
multi_model_dialogue_module
:
not_find_agent
:
'
應用不存在'
add_model
:
'
增加模型'
quit_test
:
'
退出測試'
model_setting
:
'
模型設置'
agent_system
:
'
系統人設'
remove_dialogue
:
'
移除'
one_click_configuration
:
'
一鍵配置'
select_model
:
'
選擇模型'
please_select_model
:
'
請選擇模型'
please_select_model_first
:
'
請先選擇模型'
replace_configuration_tip
:
'
是否將該模型的配置覆蓋到原來的配置項上'
open_new_conversation
:
'
已開啓新會話'
src/router/modules/dialogue.ts
0 → 100644
View file @
25671c81
import
{
type
RouteRecordRaw
}
from
'vue-router'
export
default
[
{
path
:
'/multi-model-dialogue/:agentId?'
,
name
:
'MultiModelDialogue'
,
meta
:
{
rank
:
1001
,
title
:
'router_title_module.multi_model_dialogue'
,
hideSideMenItem
:
true
,
ignoreAuth
:
true
,
},
component
:
()
=>
import
(
'@/views/multi-model-dialogue/multi-model-dialogue.vue'
),
},
]
as
RouteRecordRaw
[]
src/views/multi-model-dialogue/components/footer-operation.vue
0 → 100644
View file @
25671c81
<
script
setup
lang=
"ts"
>
import
{
computed
,
ref
}
from
'vue'
import
{
useI18n
}
from
'vue-i18n'
import
{
nanoid
}
from
'nanoid'
import
{
throttle
}
from
'lodash-es'
import
{
MessageItemInterface
,
MultiModelDialogueItem
,
QuestionMessageItem
}
from
'../types'
import
{
fetchCustomEventSource
}
from
'@/composables/useEventSource'
import
Message
from
'@/components/custom-message/message'
const
{
t
}
=
useI18n
()
interface
Props
{
agentId
:
string
isAnswerResponseWait
:
boolean
}
const
props
=
defineProps
<
Props
>
()
const
emit
=
defineEmits
<
{
addQuestionMessageItem
:
[
messageId
:
string
,
messageItem
:
MessageItemInterface
]
addAnswerMessageItem
:
[
messageId
:
string
,
messageItem
:
MessageItemInterface
,
index
:
number
]
updateMessageItem
:
[
messageId
:
string
,
messageItem
:
Partial
<
MessageItemInterface
>
,
index
:
number
]
deleteMessageItem
:
[
messageId
:
string
,
index
:
number
]
messageListScrollToBottom
:
[]
clearAllMessage
:
[]
}
>
()
const
multiModelDialogueList
=
defineModel
<
MultiModelDialogueItem
[]
>
(
'multiModelDialogueList'
,
{
required
:
true
})
const
questionContent
=
ref
(
''
)
const
isQuestionSubmitDisabled
=
computed
(()
=>
{
return
questionContent
.
value
.
trim
().
length
===
0
})
const
isAllSelectedModelName
=
computed
(()
=>
{
return
multiModelDialogueList
.
value
.
every
((
modelItem
)
=>
modelItem
.
modelNickName
)
})
const
isAllowClearAllMessage
=
computed
(()
=>
{
return
multiModelDialogueList
.
value
.
some
((
modelItem
)
=>
modelItem
.
messageList
.
size
>
0
)
})
const
messageListScrollToBottomThrottle
=
throttle
(()
=>
{
emit
(
'messageListScrollToBottom'
)
},
1000
)
function
handleClearAllMessage
()
{
isAllowClearAllMessage
.
value
&&
emit
(
'clearAllMessage'
)
}
function
messageItemFactory
()
{
return
{
role
:
'user'
,
avatar
:
''
,
nickName
:
''
,
content
:
''
,
timestamp
:
Date
.
now
(),
isTextContentLoading
:
false
,
isAnswerResponseLoading
:
false
,
}
as
MessageItemInterface
}
function
handleQuestionSubmit
()
{
if
(
isQuestionSubmitDisabled
.
value
||
props
.
isAnswerResponseWait
)
return
if
(
!
isAllSelectedModelName
.
value
)
{
window
.
$message
.
warning
(
t
(
'multi_model_dialogue_module.please_select_model_first'
))
return
}
const
questionMessageId
=
nanoid
()
emit
(
'addQuestionMessageItem'
,
questionMessageId
,
{
...
messageItemFactory
(),
content
:
questionContent
.
value
})
emit
(
'messageListScrollToBottom'
)
multiModelDialogueList
.
value
.
forEach
((
modelItem
,
modelIndex
)
=>
{
const
messages
:
QuestionMessageItem
[]
=
[]
const
{
topP
,
temperature
,
agentSystem
}
=
modelItem
modelItem
.
messageList
.
forEach
((
messageItem
)
=>
{
messages
.
push
({
content
:
[
{
type
:
'text'
,
text
:
messageItem
.
content
,
image_url
:
{
url
:
''
,
},
},
],
role
:
messageItem
.
role
,
})
})
questionContent
.
value
=
''
modelItem
.
isAnswerResponseWait
=
true
const
answerMessageId
=
nanoid
()
let
messageContent
=
''
let
isFirstClip
=
true
emit
(
'addAnswerMessageItem'
,
answerMessageId
,
{
...
messageItemFactory
(),
role
:
'assistant'
,
isTextContentLoading
:
true
,
isAnswerResponseLoading
:
true
},
modelIndex
,
)
emit
(
'messageListScrollToBottom'
)
modelItem
.
controller
=
new
AbortController
()
fetchCustomEventSource
({
path
:
'/api/rest/agentApplicationInfoRest/preview.json'
,
payload
:
{
agentId
:
props
.
agentId
,
messages
,
topP
,
temperature
,
agentSystem
,
},
controller
:
modelItem
.
controller
,
onMessage
:
(
data
:
any
)
=>
{
if
(
data
===
'[DONE]'
)
{
emit
(
'updateMessageItem'
,
answerMessageId
,
{
isAnswerResponseLoading
:
false
},
modelIndex
)
emit
(
'messageListScrollToBottom'
)
modelItem
.
isAnswerResponseWait
=
false
return
}
if
(
data
)
{
messageContent
+=
data
if
(
isFirstClip
)
{
emit
(
'updateMessageItem'
,
answerMessageId
,
{
content
:
messageContent
,
isTextContentLoading
:
false
},
modelIndex
,
)
isFirstClip
=
false
}
else
{
emit
(
'updateMessageItem'
,
answerMessageId
,
{
content
:
messageContent
},
modelIndex
)
}
messageListScrollToBottomThrottle
()
}
},
onRequestError
:
()
=>
{
errorMessageResponse
(
questionMessageId
,
answerMessageId
,
modelIndex
)
},
onFinally
:
()
=>
{
modelItem
.
controller
=
null
modelItem
.
isAnswerResponseWait
=
false
Message
({
type
:
'error'
,
text
:
'请求失败'
,
to
:
'#vvv'
})
},
})
})
}
function
errorMessageResponse
(
questionMessageId
:
string
,
answerMessageId
:
string
,
modelIndex
:
number
)
{
emit
(
'deleteMessageItem'
,
questionMessageId
,
modelIndex
)
emit
(
'deleteMessageItem'
,
answerMessageId
,
modelIndex
)
}
</
script
>
<
template
>
<footer
class=
"flex flex-col items-center"
>
<div
class=
"mb-4 flex items-center gap-[18px]"
>
<NPopover
trigger=
"hover"
>
<template
#
trigger
>
<div
class=
"border-inactive-border-color flex h-[54px] w-[54px] shrink-0 items-center justify-center rounded-full border bg-white"
:class=
"
isAllowClearAllMessage
? 'text-font-color hover:text-theme-color cursor-pointer'
: 'text-gray-font-color cursor-not-allowed'
"
@
click=
"handleClearAllMessage"
>
<i
class=
"iconfont icon-clear text-xl leading-none"
/>
</div>
</
template
>
<span
class=
"text-xs"
>
{{ t('common_module.dialogue_module.clear_message_popover_message') }}
</span>
</NPopover>
<div
class=
"relative"
>
<NInput
v-model:value=
"questionContent"
:placeholder=
"t('common_module.dialogue_module.question_input_placeholder')"
class=
"rounded-[26px]! w-[725px]! border-[#9EA3FF]! border py-[10px] pl-3 pr-[44px]"
@
keydown
.
enter=
"handleQuestionSubmit"
/>
<i
class=
"iconfont icon-send-icon absolute right-6 top-[18px] text-xl leading-none"
:class=
"
isQuestionSubmitDisabled || isAnswerResponseWait
? 'text-hover-theme-color cursor-not-allowed'
: 'text-theme-color cursor-pointer hover:opacity-80'
"
@
click=
"handleQuestionSubmit"
/>
</div>
</div>
<span
class=
"text-gray-font-color select-none"
>
{{ t('common_module.dialogue_module.generate_warning_message') }}
</span>
</footer>
</template>
src/views/multi-model-dialogue/components/message-bubble-loading.vue
0 → 100644
View file @
25671c81
<
script
setup
lang=
"ts"
>
interface
Props
{
activeColor
:
string
}
const
{
activeColor
=
'#fff'
}
=
defineProps
<
Props
>
()
</
script
>
<
template
>
<div
class=
"loader"
/>
</
template
>
<
style
lang=
"scss"
scoped
>
.loader
{
width
:
6px
;
aspect-ratio
:
1
;
border-radius
:
50%
;
animation
:
l5
1s
infinite
linear
alternate
;
}
@keyframes
l5
{
0
%
{
background
:
v-bind
(
'activeColor'
);
box-shadow
:
13px
0
v-bind
(
'activeColor'
)
,
-13px
0
#0002
;
}
33
%
{
background
:
#0002
;
box-shadow
:
13px
0
v-bind
(
'activeColor'
)
,
-13px
0
#0002
;
}
66
%
{
background
:
#0002
;
box-shadow
:
13px
0
#0002
,
-13px
0
v-bind
(
'activeColor'
);
}
100
%
{
background
:
v-bind
(
'activeColor'
);
box-shadow
:
13px
0
#0002
,
-13px
0
v-bind
(
'activeColor'
);
}
}
</
style
>
src/views/multi-model-dialogue/components/message-item.vue
0 → 100644
View file @
25671c81
<
script
setup
lang=
"ts"
>
import
{
computed
,
readonly
}
from
'vue'
import
{
useI18n
}
from
'vue-i18n'
import
type
{
MessageItemInterface
}
from
'../types'
import
MarkdownRender
from
'@/components/markdown-render/markdown-render.vue'
import
MessageBubbleLoading
from
'./message-bubble-loading.vue'
interface
Props
{
messageItem
:
MessageItemInterface
}
const
props
=
defineProps
<
Props
>
()
const
{
t
}
=
useI18n
()
const
agentAvatarUrl
=
readonly
({
url
:
'https://gsst-poe-sit.gz.bcebos.com/icon/agent-avatar.png'
})
const
isAssistant
=
computed
(()
=>
{
return
props
.
messageItem
.
role
===
'assistant'
})
const
assistantAvatarUrl
=
computed
(()
=>
{
return
props
.
messageItem
.
avatar
||
agentAvatarUrl
.
url
})
</
script
>
<
template
>
<div
class=
"mb-[20px] last:mb-0"
>
<div
class=
"flex"
>
<img
class=
"h-[36px] w-[36px] rounded-full"
:src=
"isAssistant ? assistantAvatarUrl : props.messageItem.avatar"
alt=
"Avatar"
/>
<div
class=
"ml-[11px]"
>
<div
class=
"mb-[7px] line-clamp-1 break-all text-[12px] text-[#999]"
>
{{
props
.
messageItem
.
nickName
}}
</div>
<div
class=
"box-content min-h-[21px] min-w-[10px] rounded-[10px] border border-[#9EA3FF] px-[15px] py-[12px] text-justify"
:class=
"
{
'bg-[#777EF9]': isAssistant,
'text-[#fff]': isAssistant,
'!min-w-[80px]': messageItem.isTextContentLoading,
}"
>
<div
v-if=
"messageItem.isTextContentLoading"
class=
"flex h-[21px] w-[30px] items-center justify-center"
>
<MessageBubbleLoading
:active-color=
"isAssistant ? '#fff' : '#192338'"
/>
</div>
<div
v-else
>
<MarkdownRender
:raw-text-content=
"
messageItem.content ? messageItem.content : t('common_module.dialogue_module.empty_message_content')
"
:color=
"isAssistant ? '#fff' : '#192338'"
/>
<div
v-show=
"isAssistant && messageItem.isAnswerResponseLoading"
class=
"mt-2.5 flex h-[21px] w-[30px] items-center justify-center"
>
<MessageBubbleLoading
:active-color=
"isAssistant ? '#fff' : '#192338'"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</
template
>
src/views/multi-model-dialogue/components/message-list.vue
0 → 100644
View file @
25671c81
<
script
setup
lang=
"ts"
>
import
{
useTemplateRef
}
from
'vue'
import
{
ScrollbarInst
}
from
'naive-ui'
import
MessageItem
from
'./message-item.vue'
import
type
{
MessageItemInterface
}
from
'../types'
interface
Props
{
messageList
:
Map
<
string
,
MessageItemInterface
>
}
defineProps
<
Props
>
()
defineExpose
({
scrollToBottom
,
})
const
scrollbarRef
=
useTemplateRef
<
ScrollbarInst
|
null
>
(
'scrollbarRef'
)
function
scrollToBottom
()
{
if
(
scrollbarRef
.
value
)
{
scrollbarRef
.
value
.
scrollTo
({
top
:
999999999
,
behavior
:
'smooth'
})
}
}
</
script
>
<
template
>
<div
class=
"flex-1 overflow-hidden overflow-y-auto py-[20px]"
>
<n-scrollbar
ref=
"scrollbarRef"
class=
"min-h-full"
content-class=
"min-h-full flex"
>
<div
class=
"flex flex-col-reverse"
>
<div
class=
"pr-[10px]"
>
<MessageItem
v-for=
"[key, messageItem] in messageList"
:key=
"key"
:message-item=
"messageItem"
/>
</div>
</div>
</n-scrollbar>
</div>
</
template
>
src/views/multi-model-dialogue/components/model-dialogue-item.vue
0 → 100644
View file @
25671c81
<
script
setup
lang=
"ts"
>
import
{
computed
,
h
,
nextTick
,
ref
,
useTemplateRef
}
from
'vue'
import
{
useI18n
}
from
'vue-i18n'
import
{
SelectOption
}
from
'naive-ui'
import
{
useVModel
}
from
'@vueuse/core'
import
{
MultiModelDialogueItem
}
from
'../types'
import
ModelSetting
from
'./model-setting.vue'
import
MessageList
from
'./message-list.vue'
interface
Props
{
modelDialogueItem
:
MultiModelDialogueItem
modelListOptions
:
SelectOption
[]
totalNum
:
number
isCurrent
:
boolean
}
const
{
t
}
=
useI18n
()
const
props
=
defineProps
<
Props
>
()
const
emit
=
defineEmits
<
{
removeModelDialogueItem
:
[
id
:
string
]
updateConfig
:
[
modelDialogueItem
:
MultiModelDialogueItem
]
replaceConfig
:
[
modelDialogueItem
:
MultiModelDialogueItem
]
resetConversation
:
[]
}
>
()
const
modelConfig
=
useVModel
(
props
,
'modelDialogueItem'
,
emit
)
const
messageListRef
=
useTemplateRef
<
InstanceType
<
typeof
MessageList
>>
(
'messageListRef'
)
defineExpose
({
scrollToBottom
,
})
const
isShowModelConfigMenu
=
ref
(
false
)
const
allMoreOptions
=
[
{
label
:
()
=>
h
(
'span'
,
{},
t
(
'multi_model_dialogue_module.remove_dialogue'
)),
key
:
'remove'
,
},
{
label
:
()
=>
h
(
'span'
,
{},
t
(
'multi_model_dialogue_module.one_click_configuration'
)),
key
:
'replace-config'
,
},
]
const
currentMoreOptions
=
computed
(()
=>
{
let
currentOptions
=
allMoreOptions
if
(
!
props
.
modelDialogueItem
.
modelNickName
)
{
currentOptions
=
currentOptions
.
filter
((
item
)
=>
item
.
key
!==
'replace-config'
)
}
if
(
props
.
totalNum
<=
2
)
{
currentOptions
=
currentOptions
.
filter
((
item
)
=>
item
.
key
!==
'remove'
)
}
return
currentOptions
})
// 选择更多操作
function
handleSelectMoreOption
(
key
:
string
)
{
switch
(
key
)
{
case
'remove'
:
emit
(
'removeModelDialogueItem'
,
props
.
modelDialogueItem
.
id
)
break
case
'replace-config'
:
window
.
$message
.
ctWarning
(
''
,
t
(
'multi_model_dialogue_module.replace_configuration_tip'
)).
then
(()
=>
{
emit
(
'replaceConfig'
,
props
.
modelDialogueItem
)
})
break
}
}
// 是否显示配置菜单
function
handleUpdateModelConfigShow
(
isShow
:
boolean
)
{
isShowModelConfigMenu
.
value
=
isShow
}
// 滚动到底部
function
scrollToBottom
()
{
nextTick
(()
=>
{
messageListRef
.
value
?.
scrollToBottom
()
})
}
</
script
>
<
template
>
<div
class=
"border-inactive-border-color flex flex-col overflow-hidden border-r px-6 last-of-type:border-none"
>
<div
class=
"flex items-center justify-between"
>
<div
class=
"flex items-center gap-5"
>
<n-popover
:key=
"modelConfig.id"
placement=
"bottom-start"
trigger=
"click"
:show-arrow=
"false"
:flip=
"false"
style=
"width: 386px; border-radius: 10px; box-shadow: 0 4px 13px 0 hsla(0deg, 0%, 0%, 0.08)"
@
update:show=
"handleUpdateModelConfigShow"
>
<template
#
trigger
>
<n-button
class=
"w-[145px]! !h-[34px] !rounded-[10px] !p-0"
>
<div
class=
"w-[145px]! box-border flex items-center justify-between px-[12px]"
>
<div
v-if=
"modelDialogueItem.modelNickName"
class=
"flex flex-1 items-center overflow-hidden"
>
<div
class=
"mr-[5px] h-[16px] w-[16px] rounded-full bg-cover"
:style=
"
{ backgroundImage: `url(${modelDialogueItem.icon})` }"
/>
<div
class=
"text-font-color flex-1 truncate text-start text-[14px]"
>
{{
modelDialogueItem
.
modelNickName
}}
</div>
</div>
<div
v-else
class=
"text-gray-font-color"
>
{{
t
(
'multi_model_dialogue_module.select_model'
)
}}
</div>
<i
class=
"iconfont icon-left rotate-270 text-[10px] transition-[rotate] duration-300 ease-in-out"
:class=
"
{ '!rotate-90': isShowModelConfigMenu }"
/>
</div>
</n-button>
</
template
>
<ModelSetting
v-model:model-config=
"modelConfig"
:model-list-options=
"modelListOptions"
:is-current=
"isCurrent"
@
update-config=
"(modelConfig) => emit('updateConfig', modelConfig)"
@
reset-conversation=
"emit('resetConversation')"
/>
</n-popover>
<div
v-show=
"isCurrent"
class=
"text-error-font-color font-600 select-none rounded-[10px] bg-[#FFF6F1] px-7 py-2.5 text-[13px] leading-none"
>
{{ t('common_module.currently') }}
</div>
</div>
<n-dropdown
v-if=
"currentMoreOptions.length"
trigger=
"hover"
:options=
"currentMoreOptions"
placement=
"left-start"
class=
"rounded-[10px]!"
@
select=
"handleSelectMoreOption"
>
<div
v-show=
"!isCurrent"
class=
"hover:bg-background-color flex h-6 w-6 cursor-pointer items-center justify-center rounded-full"
>
<i
class=
"iconfont icon-more text-[20px]"
/>
</div>
</n-dropdown>
</div>
<div
v-if=
"!modelDialogueItem.modelNickName"
class=
"flex flex-1 flex-col items-center justify-center"
>
<div
class=
"h-13 w-13 bg-px-empty_model-png mb-3"
/>
<span
class=
"text-font-color select-none"
>
{{ t('multi_model_dialogue_module.please_select_model') }}
</span>
</div>
<MessageList
v-else
ref=
"messageListRef"
:message-list=
"modelDialogueItem.messageList"
/>
</div>
</template>
<
style
lang=
"scss"
scoped
>
:deep
(
.model-config-input-number
.n-input__input-el
)
{
text-align
:
center
!
important
;
}
:deep
(
.agent-system-input
.n-input-wrapper
)
{
resize
:
none
!
important
;
}
</
style
>
src/views/multi-model-dialogue/components/model-setting.vue
0 → 100644
View file @
25671c81
<
script
setup
lang=
"ts"
>
import
{
computed
,
h
,
ref
,
VNodeChild
,
watch
}
from
'vue'
import
{
useI18n
}
from
'vue-i18n'
import
{
SelectOption
}
from
'naive-ui'
import
{
MultiModelDialogueItem
}
from
'../types'
import
{
DiversityModeItem
,
diversityModeList
}
from
'@/data/agent-setting-data'
interface
Props
{
modelListOptions
:
SelectOption
[]
isCurrent
:
boolean
}
const
{
t
}
=
useI18n
()
const
props
=
defineProps
<
Props
>
()
const
emit
=
defineEmits
<
{
updateConfig
:
[
modelDialogueItem
:
MultiModelDialogueItem
]
resetConversation
:
[]
}
>
()
const
modelConfig
=
defineModel
<
MultiModelDialogueItem
>
(
'modelConfig'
,
{
required
:
true
})
const
currentDiversityMode
=
ref
(
'balance'
)
const
currentModelNickName
=
computed
({
get
:
()
=>
(
modelConfig
.
value
.
modelNickName
===
''
?
undefined
:
modelConfig
.
value
.
modelNickName
),
set
:
(
newValue
)
=>
{
modelConfig
.
value
.
modelNickName
=
newValue
||
''
},
})
const
isDisabledModelConfig
=
computed
(()
=>
{
return
currentDiversityMode
.
value
!==
'custom'
})
watch
(
()
=>
modelConfig
.
value
,
(
newVal
)
=>
{
const
{
temperature
,
topP
}
=
newVal
switch
(
temperature
)
{
case
0.1
:
currentDiversityMode
.
value
=
topP
===
0.1
?
'accurate'
:
'custom'
break
case
0.5
:
currentDiversityMode
.
value
=
topP
===
0.7
?
'balance'
:
'custom'
break
case
0.95
:
currentDiversityMode
.
value
=
topP
===
0.7
?
'creative'
:
'custom'
break
default
:
currentDiversityMode
.
value
=
'custom'
}
},
{
deep
:
true
,
once
:
true
,
immediate
:
true
},
)
// 模型列表项渲染
function
modelListRenderLabel
(
option
:
SelectOption
):
VNodeChild
{
if
(
option
.
type
===
'group'
)
return
`
${
option
.
label
}
`
return
[
h
(
'div'
,
{
class
:
'flex items-center'
},
[
h
(
'div'
,
{
style
:
{
width
:
'16px'
,
height
:
'16px'
,
marginRight
:
'6px'
,
flexShrink
:
0
,
background
:
`url(
${
option
.
icon
}
)`
,
backgroundSize
:
'100% 100%'
,
},
}),
h
(
'span'
,
{},
{
default
:
()
=>
option
.
label
as
string
}),
]),
]
}
// 更新大模型
function
handleUpdateLargeModel
(
_value
:
string
,
option
:
SelectOption
)
{
modelConfig
.
value
.
icon
=
option
.
icon
as
string
emit
(
'resetConversation'
)
handleUpdateAgentConfig
()
}
// 切换生成多样性
function
handleDiversityModeChange
(
diversityModeItem
:
DiversityModeItem
)
{
const
{
value
,
topP
,
temperature
}
=
diversityModeItem
currentDiversityMode
.
value
=
value
modelConfig
.
value
.
topP
=
topP
modelConfig
.
value
.
temperature
=
temperature
handleUpdateAgentConfig
()
}
// 更新保存应用配置
function
handleUpdateAgentConfig
()
{
props
.
isCurrent
&&
emit
(
'updateConfig'
,
modelConfig
.
value
)
}
</
script
>
<
template
>
<div
class=
"px-1.5 py-1"
>
<p
class=
"text-font-color font-600 mb-2 select-none"
>
{{
t
(
'multi_model_dialogue_module.model_setting'
)
}}
</p>
<n-select
v-model:value=
"currentModelNickName"
:options=
"modelListOptions"
:render-label=
"modelListRenderLabel"
:placeholder=
"t('multi_model_dialogue_module.please_select_model')"
@
update:value=
"handleUpdateLargeModel"
/>
<p
class=
"text-font-color font-600 mb-2 mt-[14px] select-none"
>
{{
t
(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.generate_diversity'
)
}}
</p>
<ul
class=
"rounded-theme mt-2 grid grid-cols-4 overflow-hidden"
>
<li
v-for=
"(diversityModeItem, index) in diversityModeList"
:key=
"index"
class=
"hover:text-font-color flex h-[34px] w-full cursor-pointer items-center justify-center"
:class=
"
currentDiversityMode === diversityModeItem.value
? 'text-font-color bg-active-color'
: 'text-gray-font-color bg-[#F7F7FA]'
"
@
click=
"handleDiversityModeChange(diversityModeItem)"
>
{{
t
(
diversityModeItem
.
label
)
}}
</li>
</ul>
<div
class=
"mb-3 mt-[14px] flex h-[34px] items-center justify-between"
>
<div
class=
"flex w-[70px] items-center"
>
<span
class=
"text-font-color font-600 select-none"
>
{{
t
(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.temperature'
)
}}
</span>
</div>
<div
class=
"mx-3 flex flex-1"
>
<n-slider
v-model:value=
"modelConfig.temperature"
:default-value=
"0"
:step=
"0.01"
:min=
"0.01"
:max=
"1"
:disabled=
"isDisabledModelConfig"
@
update:value=
"handleUpdateAgentConfig"
/>
</div>
<n-input-number
v-model:value=
"modelConfig.temperature"
:bordered=
"false"
:step=
"0.01"
:min=
"0"
:max=
"1"
:disabled=
"isDisabledModelConfig"
placeholder=
""
button-placement=
"both"
class=
"w-[100px]! model-config-input-number"
@
update:value=
"handleUpdateAgentConfig"
>
<template
#
minus-icon
>
<div
class=
"border-inactive-border-color h-6! w-6! rounded-theme flex shrink-0 items-center justify-center border"
>
<i
class=
"iconfont icon-minus"
/>
</div>
</
template
>
<
template
#
add-icon
>
<div
class=
"border-inactive-border-color h-6! w-6! rounded-theme flex shrink-0 items-center justify-center border"
>
<i
class=
"iconfont icon-add"
/>
</div>
</
template
>
</n-input-number>
</div>
<div
class=
"mt-4 text-xs"
>
<div
class=
"mb-3 flex h-[34px] items-center justify-between"
>
<div
class=
"flex w-[70px] items-center"
>
<span
class=
"text-font-color font-600 select-none"
>
{{ t('personal_space_module.agent_module.agent_setting_module.agent_config_module.topP') }}
</span>
</div>
<div
class=
"mx-3 flex flex-1"
>
<n-slider
v-model:value=
"modelConfig.topP"
:default-value=
"0"
:step=
"0.01"
:min=
"0"
:max=
"1"
:disabled=
"isDisabledModelConfig"
@
update:value=
"handleUpdateAgentConfig"
/>
</div>
<n-input-number
v-model:value=
"modelConfig.topP"
:bordered=
"false"
:step=
"0.01"
:min=
"0"
:max=
"1"
:disabled=
"isDisabledModelConfig"
placeholder=
""
button-placement=
"both"
class=
"w-[100px]! model-config-input-number"
@
update:value=
"handleUpdateAgentConfig"
>
<
template
#
minus-icon
>
<div
class=
"border-inactive-border-color h-6! w-6! rounded-theme flex shrink-0 items-center justify-center border"
>
<i
class=
"iconfont icon-minus"
/>
</div>
</
template
>
<
template
#
add-icon
>
<div
class=
"border-inactive-border-color h-6! w-6! rounded-theme flex shrink-0 items-center justify-center border"
>
<i
class=
"iconfont icon-add"
/>
</div>
</
template
>
</n-input-number>
</div>
</div>
<p
class=
"text-font-color font-600 mb-1.5 select-none"
>
{{ t('multi_model_dialogue_module.agent_system') }}
</p>
<n-input
v-model:value=
"modelConfig.agentSystem"
type=
"textarea"
placeholder=
""
:rows=
"10"
class=
"agent-system-input"
@
update:value=
"handleUpdateAgentConfig"
/>
</div>
</template>
src/views/multi-model-dialogue/components/page-header.vue
0 → 100644
View file @
25671c81
<
script
setup
lang=
"ts"
>
import
{
computed
}
from
'vue'
import
{
useI18n
}
from
'vue-i18n'
import
{
Left
,
Plus
,
Logout
}
from
'@icon-park/vue-next'
interface
Props
{
agentTitle
:
string
agentDesc
:
string
totalNum
:
number
isAnswerResponseWait
:
boolean
}
const
{
t
}
=
useI18n
()
const
props
=
defineProps
<
Props
>
()
const
isDisabledAddModelBtn
=
computed
(()
=>
{
return
props
.
totalNum
>=
3
||
props
.
isAnswerResponseWait
})
const
emit
=
defineEmits
<
{
back
:
[]
addModelDialogue
:
[]
}
>
()
function
handleBack
()
{
emit
(
'back'
)
}
function
handleAddModelDialogue
()
{
emit
(
'addModelDialogue'
)
}
</
script
>
<
template
>
<header
class=
"mb-[18px] flex items-end justify-between"
>
<div>
<div
class=
"flex items-center"
>
<div
class=
"rounded-theme hover:bg-hover-background-color mr-0.5 flex h-7 w-7 cursor-pointer items-center justify-center"
@
click=
"handleBack"
>
<Left
theme=
"outline"
size=
"20"
fill=
"#333"
class=
"mt-0.5"
/>
</div>
<span
class=
"text-font-color font-600 line-clamp-1 break-all text-lg"
>
{{
agentTitle
||
'--'
}}
</span>
</div>
<span
class=
"text-gray-font-color ml-7.5 mt-1.5 line-clamp-1 break-all"
>
{{
agentDesc
||
t
(
'personal_space_module.agent_module.agent_setting_module.missing_agent_desc_message'
)
}}
</span>
</div>
<div
class=
"flex gap-5"
>
<NButton
type=
"primary"
:bordered=
"false"
class=
"px-4!"
:disabled=
"isDisabledAddModelBtn"
@
click=
"handleAddModelDialogue"
>
<Plus
theme=
"outline"
size=
"16"
fill=
"#fff"
:stroke-width=
"4"
/>
<span
class=
"ml-[5px]"
>
{{
t
(
'multi_model_dialogue_module.add_model'
)
}}{{
totalNum
}}
/3
</span>
</NButton>
<NButton
type=
"info"
@
click=
"handleBack"
>
<Logout
theme=
"outline"
size=
"16"
fill=
"#575FFF"
:stroke-width=
"4"
/>
<span
class=
"ml-[5px]"
>
{{
t
(
'multi_model_dialogue_module.quit_test'
)
}}
</span>
</NButton>
</div>
</header>
</
template
>
src/views/multi-model-dialogue/multi-model-dialogue.vue
0 → 100644
View file @
25671c81
This diff is collapsed.
Click to expand it.
src/views/multi-model-dialogue/types.d.ts
0 → 100644
View file @
25671c81
export
interface
QuestionMessageItem
{
role
:
'user'
|
'assistant'
content
:
[
{
type
:
string
text
:
string
image_url
:
{
url
:
string
}
},
]
}
export
interface
MultiModelDialogueItem
{
id
:
string
icon
:
string
modelNickName
:
string
topP
:
number
temperature
:
number
agentSystem
:
string
controller
:
AbortController
|
null
isAnswerResponseWait
:
boolean
messageList
:
Map
<
string
,
MessageItemInterface
>
}
export
interface
MessageItemInterface
{
role
:
'user'
|
'assistant'
avatar
:
string
nickName
:
string
content
:
string
timestamp
:
number
isTextContentLoading
:
boolean
isAnswerResponseLoading
:
boolean
}
src/views/personal-space/personal-app-setting/components/app-preview.vue
View file @
25671c81
<
script
setup
lang=
"ts"
>
<
script
setup
lang=
"ts"
>
import
{
ref
}
from
'vue'
import
{
ref
}
from
'vue'
import
{
useRouter
}
from
'vue-router'
import
Preamble
from
'./preamble.vue'
import
Preamble
from
'./preamble.vue'
import
{
useI18n
}
from
'vue-i18n'
import
{
useI18n
}
from
'vue-i18n'
import
MessageList
from
'./message-list.vue'
import
MessageList
from
'./message-list.vue'
...
@@ -9,6 +10,8 @@ import { usePersonalAppConfigStore } from '@/store/modules/personal-app-config'
...
@@ -9,6 +10,8 @@ import { usePersonalAppConfigStore } from '@/store/modules/personal-app-config'
const
{
t
}
=
useI18n
()
const
{
t
}
=
useI18n
()
const
router
=
useRouter
()
const
personalAppConfigStore
=
usePersonalAppConfigStore
()
const
personalAppConfigStore
=
usePersonalAppConfigStore
()
const
messageListRef
=
ref
<
InstanceType
<
typeof
MessageList
>
|
null
>
(
null
)
const
messageListRef
=
ref
<
InstanceType
<
typeof
MessageList
>
|
null
>
(
null
)
...
@@ -67,14 +70,34 @@ function handleUpdateContinueQuestionStatus(status: 'default' | 'close') {
...
@@ -67,14 +70,34 @@ function handleUpdateContinueQuestionStatus(status: 'default' | 'close') {
continuousQuestionStatus
.
value
=
status
continuousQuestionStatus
.
value
=
status
continuousQuestionList
.
value
=
[]
continuousQuestionList
.
value
=
[]
}
}
function
handleTurnMultiModelDialogue
()
{
router
.
push
({
name
:
'MultiModelDialogue'
,
params
:
{
agentId
:
personalAppConfigStore
.
baseInfo
.
agentId
,
},
})
}
</
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=
"mb-[18px] flex items-center justify-between px-5 py-[18px]"
>
<p
class=
"text-base"
>
{{
t
(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.preview'
)
}}
{{
t
(
'personal_space_module.agent_module.agent_setting_module.agent_config_module.preview'
)
}}
</p>
</p>
<div
v-show=
"personalAppConfigStore.baseInfo.agentId"
class=
"text-font-color hover:text-theme-color cursor-pointer"
@
click=
"handleTurnMultiModelDialogue"
>
<i
class=
"iconfont icon-moxing mr-1 text-sm"
/>
<span>
{{
t
(
'common_module.multi_model_debug'
)
}}
</span>
</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"
>
<Preamble
/>
<Preamble
/>
...
...
types/locales.d.ts
View file @
25671c81
...
@@ -54,6 +54,11 @@ declare namespace I18n {
...
@@ -54,6 +54,11 @@ declare namespace I18n {
select_all
:
string
select_all
:
string
quit
:
string
quit
:
string
retry
:
string
retry
:
string
currently
:
string
multi_model_debug
:
string
accurate_mode
:
string
balance_mode
:
string
creative_mode
:
string
dialogue_module
:
{
dialogue_module
:
{
continue_question_message
:
string
continue_question_message
:
string
...
@@ -130,6 +135,7 @@ declare namespace I18n {
...
@@ -130,6 +135,7 @@ declare namespace I18n {
upload_knowledge_document
:
string
upload_knowledge_document
:
string
knowledge_document_list
:
string
knowledge_document_list
:
string
knowledge_document_detail
:
string
knowledge_document_detail
:
string
multi_model_dialogue
:
string
}
}
personal_space_module
:
{
personal_space_module
:
{
...
@@ -309,5 +315,20 @@ declare namespace I18n {
...
@@ -309,5 +315,20 @@ declare namespace I18n {
create_agent_dialogue_content
:
string
create_agent_dialogue_content
:
string
create_agent_dialogue_positive_text
:
string
create_agent_dialogue_positive_text
:
string
}
}
multi_model_dialogue_module
:
{
not_find_agent
:
string
add_model
:
string
quit_test
:
string
model_setting
:
string
agent_system
:
string
remove_dialogue
:
string
one_click_configuration
:
string
select_model
:
string
please_select_model
:
string
please_select_model_first
:
string
replace_configuration_tip
:
string
open_new_conversation
:
string
}
}
}
}
}
uno.config.ts
View file @
25671c81
...
@@ -54,6 +54,7 @@ export default defineConfig({
...
@@ -54,6 +54,7 @@ export default defineConfig({
'error-font-color'
:
'#F25744'
,
'error-font-color'
:
'#F25744'
,
'inactive-border-color'
:
'#CCCCCC'
,
'inactive-border-color'
:
'#CCCCCC'
,
'background-color'
:
'#F3F5F8'
,
'background-color'
:
'#F3F5F8'
,
'hover-background-color'
:
'#E3E8F0'
,
},
},
height
:
{
height
:
{
navbar
:
'56px'
,
navbar
:
'56px'
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment