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
7fd27d15
Commit
7fd27d15
authored
Sep 24, 2024
by
nick zheng
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 应用增加AI自动配置
parent
69e0b200
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
322 additions
and
28 deletions
+322
-28
agent-application.ts
src/apis/agent-application.ts
+29
-6
custom-modal.vue
src/components/custom-modal/custom-modal.vue
+7
-3
app-setting.vue
...nal-space/personal-app-setting/components/app-setting.vue
+184
-19
auto-config-modal.vue
...ace/personal-app-setting/components/auto-config-modal.vue
+102
-0
No files found.
src/apis/agent-application.ts
View file @
7fd27d15
...
...
@@ -78,31 +78,54 @@ export function fetchCreateContinueQuestions<T>(payload: { input: string }) {
}
/**
* * @param {
agentTitle: 标题 agentDesc: 描述
}
* * @param {
payload: { agentTitle: 标题 agentDesc: 描述 }, controller: 控制取消请求
}
* @returns AI生成应用头像
*/
export
function
fetchCreateAgentAvatar
<
T
>
(
payload
:
{
agentTitle
:
string
;
agentDesc
:
string
})
{
export
function
fetchCreateAgentAvatar
<
T
>
(
payload
:
{
agentTitle
:
string
;
agentDesc
:
string
},
controller
:
AbortController
,
)
{
return
request
.
post
<
T
>
(
'/agentApplicationInfoRest/createAgentApplicationAvatar.json'
,
payload
,
{
timeout
:
120000
,
signal
:
controller
.
signal
,
})
}
/**
* * @param {
agentTitle: 标题 agentDesc: 描述 agentSystem: 指令
}
* * @param {
payload: { agentTitle: 标题, agentDesc: 描述, agentSystem: 指令 }, controller: 控制取消请求
}
* @returns AI生成开场白
*/
export
function
fetchCreatePreamble
<
T
>
(
payload
:
{
agentTitle
:
string
;
agentDesc
:
string
;
agentSystem
:
string
})
{
export
function
fetchCreatePreamble
<
T
>
(
payload
:
{
agentTitle
:
string
;
agentDesc
:
string
;
agentSystem
:
string
},
controller
:
AbortController
,
)
{
return
request
.
post
<
T
>
(
'/agentApplicationInfoRest/createPreamble.json'
,
payload
,
{
timeout
:
120000
,
signal
:
controller
.
signal
,
})
}
/**
* * @param {
agentTitle: 标题 agentDesc: 描述
}
* * @param {
payload: { agentTitle: 标题 agentDesc: 描述 }, controller: 控制取消请求
}
* @returns AI生成推荐问
*/
export
function
fetchCreateFeaturedQuestions
<
T
>
(
payload
:
{
agentTitle
:
string
;
agentDesc
:
string
})
{
export
function
fetchCreateFeaturedQuestions
<
T
>
(
payload
:
{
agentTitle
:
string
;
agentDesc
:
string
},
controller
:
AbortController
,
)
{
return
request
.
post
<
T
>
(
'/agentApplicationInfoRest/createFeaturedQuestions.json'
,
payload
,
{
timeout
:
120000
,
signal
:
controller
.
signal
,
})
}
/**
* * @param { payload: { input: 自动配置信息 }, controller: 控制取消请求 }
* @returns 生成应用标题和描述
*/
export
function
fetchCreateAgentTitleAndDesc
<
T
>
(
payload
:
{
input
:
string
},
controller
:
AbortController
)
{
return
request
.
post
<
T
>
(
'/agentApplicationInfoRest/createAgentTitleAndDesc.json'
,
payload
,
{
timeout
:
120000
,
signal
:
controller
.
signal
,
})
}
src/components/custom-modal/custom-modal.vue
View file @
7fd27d15
<
script
setup
lang=
"ts"
>
import
{
computed
}
from
'vue'
import
{
computed
,
useSlots
}
from
'vue'
import
{
modalHeaderStyle
,
modalContentStyle
,
modalFooterStyle
}
from
'./modal-style'
interface
Props
{
...
...
@@ -36,9 +36,11 @@ const props = withDefaults(defineProps<Props>(), {
const
emit
=
defineEmits
<
Emits
>
()
const
slots
=
useSlots
()
const
modalBasicStyle
=
{
width
:
props
.
width
+
'px'
,
h
eight
:
props
.
height
+
'px'
,
minH
eight
:
props
.
height
+
'px'
,
borderRadius
:
props
.
borderRadius
+
'px'
,
}
...
...
@@ -85,7 +87,9 @@ function handleDetele() {
</div>
<
template
#
footer
>
<div
class=
"flex w-full items-center justify-end"
>
<slot
v-if=
"slots.footer"
name=
"footer"
/>
<div
v-else
class=
"flex w-full items-center justify-end"
>
<NButton
class=
"h-[32px]! rounded-md! px-6!"
@
click=
"handleCloseModal"
>
{{
cancelBtnText
}}
</NButton>
<NButton
:loading=
"btnLoading"
...
...
src/views/personal-space/personal-app-setting/components/app-setting.vue
View file @
7fd27d15
<
script
setup
lang=
"ts"
>
import
{
computed
,
onM
ounted
,
reactive
,
ref
,
watch
}
from
'vue'
import
{
computed
,
nextTick
,
onMounted
,
onUnm
ounted
,
reactive
,
ref
,
watch
}
from
'vue'
import
{
useRouter
}
from
'vue-router'
import
{
FormInst
,
SelectOption
,
UploadFileInfo
}
from
'naive-ui'
import
{
FormInst
,
InputInst
,
SelectOption
,
UploadFileInfo
}
from
'naive-ui'
import
{
useThrottleFn
}
from
'@vueuse/core'
import
CustomIcon
from
'@/components/custom-icon/custom-icon.vue'
import
UploadPhoto
from
'@/components/upload-photo/upload-photo.vue'
import
AutoConfigModal
from
'./auto-config-modal.vue'
import
OptimizeSystemModal
from
'./optimize-system-modal.vue'
import
{
usePersonalAppConfigStore
}
from
'@/store/modules/personal-app-config'
import
{
PersonalAppConfigState
}
from
'@/store/types/personal-app-config'
import
{
fetchCreateAgentAvatar
,
fetchCreateAgentTitleAndDesc
,
fetchCreateFeaturedQuestions
,
fetchCreatePreamble
,
fetchGetDebugApplicationInfo
,
fetchGetLargeModelList
,
fetchSaveAgentApplication
,
}
from
'@/apis/agent-application'
import
{
fetchCustomEventSource
}
from
'@/composables/useEventSource'
const
router
=
useRouter
()
...
...
@@ -52,6 +55,10 @@ const commConfigExpandedNames = ref<string[]>(['continuousQuestion'])
const
isInitGetAgentAppDetail
=
ref
(
false
)
const
isFullScreenLoading
=
ref
(
false
)
// 是否全面加载中
const
isShowAutoConfigModal
=
ref
(
false
)
// 是否显示自动配置对话框
const
autoConfigBtnLoading
=
ref
(
false
)
// 自动配置按钮加载状态
const
isShowOptimizeAgentSystemModal
=
ref
(
false
)
// 是否显示优化角色指令对话框
const
generateAgentAvatarLoading
=
ref
(
false
)
// 是否正在生成图片
...
...
@@ -59,6 +66,7 @@ const generatePreambleLoading = ref(false) // 是否正在生成开场白
const
generateFeaturedQuestionsLoading
=
ref
(
false
)
// 是否正在生成推荐词
const
personalAppFormRef
=
ref
<
FormInst
|
null
>
(
null
)
const
agentSystemInputRef
=
ref
<
InputInst
|
null
>
(
null
)
const
personalAppRules
=
{
baseInfo
:
{
...
...
@@ -66,6 +74,12 @@ const personalAppRules = {
},
}
let
generateAgentTitleAndDescController
:
AbortController
|
null
=
null
let
generateAgentAvatarController
:
AbortController
|
null
=
null
let
generatePreambleController
:
AbortController
|
null
=
null
let
generateFeaturedQuestionsController
:
AbortController
|
null
=
null
let
generateAgentSystemController
:
AbortController
|
null
=
null
const
personalAppConfig
=
computed
(()
=>
{
return
personalAppConfigStore
.
$state
})
...
...
@@ -74,10 +88,14 @@ const continuousQuestionStatusText = computed(() => {
return
personalAppConfig
.
value
.
commConfig
.
continuousQuestionStatus
===
'default'
?
'默认'
:
'关闭'
})
const
isUpdatePersonalAgentConfig
=
computed
(()
=>
{
return
!
isInitGetAgentAppDetail
.
value
})
watch
(
()
=>
personalAppConfig
.
value
,
()
=>
{
!
isInitGetAgentAppDetail
.
value
&&
handleUpdatePersonalAppId
()
isUpdatePersonalAgentConfig
.
value
&&
handleUpdatePersonalAppId
()
},
{
deep
:
true
,
once
:
true
},
)
...
...
@@ -85,7 +103,7 @@ watch(
watch
(
()
=>
personalAppConfig
.
value
,
()
=>
{
!
isInitGetAgentAppDetail
.
value
&&
handleSavePersonalAppConfig
()
isUpdatePersonalAgentConfig
.
value
&&
handleSavePersonalAppConfig
()
},
{
deep
:
true
},
)
...
...
@@ -99,11 +117,15 @@ onMounted(async () => {
await
handleGetLargeModelList
()
})
onUnmounted
(()
=>
{
handleStopGenerate
()
})
const
handleSavePersonalAppConfig
=
useThrottleFn
(
async
()
=>
{
personalAppConfig
.
value
.
baseInfo
.
agentId
&&
(
await
handleSaveAgentApplication
())
},
2000
,
()
=>
(
isFullScreenLoading
.
value
?
6000
:
2000
)
,
true
,
)
...
...
@@ -155,6 +177,11 @@ async function handleUpdatePersonalAppId() {
}
}
function
handleShowAutoConfigModal
()
{
isShowAutoConfigModal
.
value
=
true
autoConfigBtnLoading
.
value
=
false
}
function
handleShowOptimizeAgentSystemModal
()
{
if
(
!
personalAppConfig
.
value
.
baseInfo
.
agentSystem
)
return
...
...
@@ -179,11 +206,15 @@ function handleUpdateCommConfigExpandedNames(expandedNames: string[]) {
async
function
handleAIGenerateAgentAvatar
()
{
generateAgentAvatarLoading
.
value
=
true
generateAgentAvatarController
=
new
AbortController
()
const
res
=
await
fetchCreateAgentAvatar
({
const
res
=
await
fetchCreateAgentAvatar
(
{
agentTitle
:
personalAppConfig
.
value
.
baseInfo
.
agentTitle
,
agentDesc
:
personalAppConfig
.
value
.
baseInfo
.
agentDesc
,
}).
finally
(()
=>
(
generateAgentAvatarLoading
.
value
=
false
))
},
generateAgentAvatarController
,
).
finally
(()
=>
(
generateAgentAvatarLoading
.
value
=
false
))
if
(
res
.
code
===
0
)
{
personalAppConfig
.
value
.
baseInfo
.
agentAvatar
=
res
.
data
as
string
...
...
@@ -195,11 +226,16 @@ async function handleAIGeneratePreamble() {
generatePreambleLoading
.
value
=
true
const
res
=
await
fetchCreatePreamble
<
string
>
({
generatePreambleController
=
new
AbortController
()
const
res
=
await
fetchCreatePreamble
<
string
>
(
{
agentTitle
:
personalAppConfig
.
value
.
baseInfo
.
agentTitle
,
agentDesc
:
personalAppConfig
.
value
.
baseInfo
.
agentDesc
,
agentSystem
:
personalAppConfig
.
value
.
baseInfo
.
agentSystem
,
}).
finally
(()
=>
(
generatePreambleLoading
.
value
=
false
))
},
generatePreambleController
,
).
finally
(()
=>
(
generatePreambleLoading
.
value
=
false
))
if
(
res
.
code
===
0
)
{
try
{
...
...
@@ -217,21 +253,119 @@ async function handleAIGenerateFeaturedQuestions() {
commConfigExpandedNames
.
value
.
push
(
'featuredQuestions'
)
generateFeaturedQuestionsLoading
.
value
=
true
generateFeaturedQuestionsController
=
new
AbortController
()
const
res
=
await
fetchCreateFeaturedQuestions
<
string
[]
>
({
const
res
=
await
fetchCreateFeaturedQuestions
<
string
[]
>
(
{
agentTitle
:
personalAppConfig
.
value
.
baseInfo
.
agentTitle
,
agentDesc
:
personalAppConfig
.
value
.
baseInfo
.
agentDesc
,
}).
finally
(()
=>
(
generateFeaturedQuestionsLoading
.
value
=
false
))
},
generateFeaturedQuestionsController
,
).
finally
(()
=>
(
generateFeaturedQuestionsLoading
.
value
=
false
))
if
(
res
.
code
===
0
)
{
personalAppConfig
.
value
.
commConfig
.
featuredQuestions
=
res
.
data
}
}
async
function
handleSettingAgent
(
autoConfigInputValue
:
string
)
{
autoConfigBtnLoading
.
value
=
true
isShowAutoConfigModal
.
value
=
false
isFullScreenLoading
.
value
=
true
await
handleCreateAgentTitleAndDesc
(
autoConfigInputValue
)
.
then
(()
=>
{
Promise
.
all
([
handleAIGenerateAgentAvatar
(),
handleAIGeneratePreamble
(),
handleAIGenerateFeaturedQuestions
(),
handleAIGenerateAgentSystem
(),
]).
finally
(()
=>
{
isFullScreenLoading
.
value
=
false
})
})
.
catch
(()
=>
{
isFullScreenLoading
.
value
=
false
})
}
async
function
handleCreateAgentTitleAndDesc
(
input
:
string
)
{
generateAgentTitleAndDescController
=
new
AbortController
()
const
res
=
await
fetchCreateAgentTitleAndDesc
<
{
agentTitle
:
string
;
agentDesc
:
string
}
>
(
{
input
},
generateAgentTitleAndDescController
,
)
if
(
res
.
code
===
0
)
{
personalAppConfig
.
value
.
baseInfo
.
agentTitle
=
res
.
data
.
agentTitle
personalAppConfig
.
value
.
baseInfo
.
agentDesc
=
res
.
data
.
agentDesc
}
}
function
handleSettingAgentSystem
(
agentSystem
:
string
)
{
personalAppConfig
.
value
.
baseInfo
.
agentSystem
=
agentSystem
isShowOptimizeAgentSystemModal
.
value
=
false
}
function
handleAIGenerateAgentSystem
()
{
return
new
Promise
((
resolve
,
reject
)
=>
{
personalAppConfig
.
value
.
baseInfo
.
agentSystem
=
''
generateAgentSystemController
=
new
AbortController
()
fetchCustomEventSource
({
path
:
'/api/rest/agentApplicationInfoRest/createAgentSystem.json'
,
payload
:
{
input
:
personalAppConfigStore
.
baseInfo
.
agentSystem
,
},
controller
:
generateAgentSystemController
,
onMessage
:
(
data
:
any
)
=>
{
if
(
data
===
'[DONE]'
)
{
blockAnswerResponse
()
resolve
(
data
)
return
}
if
(
data
)
{
useThrottleFn
(
()
=>
{
nextTick
(()
=>
{
personalAppConfig
.
value
.
baseInfo
.
agentSystem
+=
data
agentSystemInputRef
.
value
!
.
textareaElRef
!
.
scrollTop
=
agentSystemInputRef
.
value
?.
textareaElRef
?.
scrollHeight
||
0
})
},
1000
,
true
,
)()
}
},
onRequestError
:
()
=>
{
reject
()
blockAnswerResponse
()
},
onError
:
()
=>
{
reject
()
blockAnswerResponse
()
},
onFinally
:
()
=>
{
generateAgentSystemController
=
null
},
})
})
}
function
blockAnswerResponse
()
{
generateAgentSystemController
?.
abort
()
}
function
handleStopGenerate
()
{
generateAgentTitleAndDescController
?.
abort
()
generateAgentAvatarController
?.
abort
()
generatePreambleController
?.
abort
()
generateFeaturedQuestionsController
?.
abort
()
generateAgentSystemController
?.
abort
()
isFullScreenLoading
.
value
=
false
}
</
script
>
<
template
>
...
...
@@ -239,8 +373,18 @@ function handleSettingAgentSystem(agentSystem: string) {
<div
class=
"flex h-[56px] w-full items-center justify-between border-r border-[#e8e9eb] px-5 text-[#333] shadow-[inset_0_-1px_#e8e9eb]"
>
<div
class=
"flex items-center"
>
<span
class=
"font-600 mr-4 text-base"
>
应用配置
</span>
<div
class=
"text-theme-color flex cursor-pointer items-center rounded-md border border-[#d4e5ff] bg-[#eef3fe] px-[11px] py-[7px] text-xs hover:opacity-80"
@
click=
"handleShowAutoConfigModal"
>
<div
class=
"mr-2 mt-[-4px] h-[16px] w-[16px] bg-[url(@/assets/svgs/star.svg)] bg-[length:100%_100%]"
/>
<span>
AI自动配置
</span>
</div>
</div>
<div>
<NPopover
placement=
"bottom"
trigger=
"click"
style=
"width: 420px"
>
<template
#
trigger
>
...
...
@@ -474,6 +618,7 @@ function handleSettingAgentSystem(agentSystem: string) {
<div
class=
"flex flex-1 p-1 pl-6"
>
<NInput
ref=
"agentSystemInputRef"
v-model:value=
"personalAppConfig.baseInfo.agentSystem"
type=
"textarea"
class=
"prompt-input not-resize text-xs! flex-1"
...
...
@@ -626,6 +771,26 @@ function handleSettingAgentSystem(agentSystem: string) {
</div>
</div>
<div
v-show=
"isFullScreenLoading"
class=
"z-999 fixed bottom-0 left-0 right-0 top-0 flex items-center justify-center bg-[#151b2680]"
>
<div
class=
"flex h-14 w-[300px] items-center justify-between rounded-xl bg-white px-5"
>
<div
class=
"flex items-center"
>
<div
class=
"mr-2 h-4 w-4 bg-[url(@/assets/images/loading.gif)] bg-[length:100%_100%]"
/>
<span
class=
"text-theme-color"
>
配置信息生成中...
</span>
</div>
<div
class=
"cursor-pointer text-[#5c5f66] hover:opacity-80"
@
click=
"handleStopGenerate"
>
停止生成
</div>
</div>
</div>
<AutoConfigModal
v-model:is-show-modal=
"isShowAutoConfigModal"
:btn-loading=
"autoConfigBtnLoading"
modal-title=
"AI生成配置信息"
@
comfirm=
"handleSettingAgent"
/>
<OptimizeSystemModal
v-model:is-show-modal=
"isShowOptimizeAgentSystemModal"
:btn-loading=
"false"
...
...
src/views/personal-space/personal-app-setting/components/auto-config-modal.vue
0 → 100644
View file @
7fd27d15
<
script
setup
lang=
"ts"
>
import
{
computed
,
ref
,
watch
}
from
'vue'
import
CustomModal
from
'@/components/custom-modal/custom-modal.vue'
import
CustomIcon
from
'@/components/custom-icon/custom-icon.vue'
interface
Props
{
isShowModal
:
boolean
btnLoading
:
boolean
modalTitle
:
string
}
interface
Emits
{
(
e
:
'update:isShowModal'
,
value
:
boolean
):
void
(
e
:
'comfirm'
,
value
:
string
):
void
}
const
props
=
defineProps
<
Props
>
()
const
emit
=
defineEmits
<
Emits
>
()
const
autoConfigInputValue
=
ref
(
''
)
const
autoConfigInputType
=
ref
<
'random'
|
'input'
>
(
'random'
)
const
showModal
=
computed
({
get
()
{
return
props
.
isShowModal
},
set
(
value
:
boolean
)
{
emit
(
'update:isShowModal'
,
value
)
},
})
const
isDisabledBtn
=
computed
(()
=>
{
return
!
autoConfigInputValue
.
value
})
const
isRandomBtnLoading
=
computed
(()
=>
{
return
props
.
btnLoading
&&
autoConfigInputType
.
value
===
'random'
})
const
isInputBtnLoading
=
computed
(()
=>
{
return
props
.
btnLoading
&&
autoConfigInputType
.
value
===
'input'
})
watch
(
()
=>
showModal
.
value
,
()
=>
{
showModal
.
value
&&
(
autoConfigInputValue
.
value
=
''
)
},
)
function
handleCloseModal
()
{
emit
(
'update:isShowModal'
,
false
)
}
function
handleComfirm
(
inputType
:
'random'
|
'input'
)
{
autoConfigInputType
.
value
=
inputType
emit
(
'comfirm'
,
inputType
===
'random'
?
''
:
autoConfigInputValue
.
value
)
}
</
script
>
<
template
>
<CustomModal
v-model:is-show=
"showModal"
:title=
"modalTitle"
:width=
"600"
>
<template
#
content
>
<div
class=
"mb-3 flex h-8 w-full items-center rounded bg-[#FFF4E6] px-4"
>
<CustomIcon
icon=
"ep:warning-filled"
class=
"mr-2 h-4 w-4 text-[#FFA500]"
/>
<span>
生成结果将覆盖当前的配置内容,请确认是否继续生成
</span>
</div>
<NInput
v-model:value=
"autoConfigInputValue"
type=
"textarea"
:rows=
"10"
:disabled=
"false"
placeholder=
"请告诉我你想创建一个什么样的应用,大模型将为你自动生成"
class=
"rounded-lg!"
/>
</
template
>
<
template
#
footer
>
<div
class=
"flex w-full items-center justify-end"
>
<NButton
class=
"h-[32px]! rounded-md! px-6!"
@
click=
"handleCloseModal"
>
取 消
</NButton>
<NButton
:loading=
"isRandomBtnLoading"
class=
"h-[32px]! rounded-md! px-6! ml-4!"
@
click=
"handleComfirm('random')"
>
随机生成
</NButton>
<NButton
:loading=
"isInputBtnLoading"
type=
"primary"
:disabled=
"isDisabledBtn"
class=
"h-[32px]! px-6! rounded-md! ml-4!"
@
click=
"handleComfirm('input')"
>
AI生成
</NButton>
</div>
</
template
>
</CustomModal>
</template>
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