mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 01:33:05 +00:00
feat: Consciousness recognition node
This commit is contained in:
parent
16ade76446
commit
7af880f1db
|
|
@ -173,7 +173,7 @@
|
|||
v-if="
|
||||
data.type == WorkflowType.AiChat ||
|
||||
data.type == WorkflowType.Question ||
|
||||
data.type == WorkflowType.Application
|
||||
data.type == WorkflowType.Application || data.type == WorkflowType.IntentNode
|
||||
"
|
||||
>
|
||||
<div class="card-never border-r-6" v-if="data.type !== WorkflowType.Application">
|
||||
|
|
|
|||
|
|
@ -329,6 +329,7 @@ export default {
|
|||
},
|
||||
intentNode: {
|
||||
label: 'IntentNode',
|
||||
text: 'Match user questions with user-defined intent classifications',
|
||||
other: 'other',
|
||||
placeholder: 'Please choose a classification option',
|
||||
classify: {
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ export default {
|
|||
continue: 'Continue Generating',
|
||||
replace: 'Replace',
|
||||
exit: 'Are you sure you want to exit and discard the AI-generated content?',
|
||||
loading: 'Generating...',
|
||||
},
|
||||
dialog: {
|
||||
addKnowledge: 'Add Related Knowledge',
|
||||
|
|
|
|||
|
|
@ -329,6 +329,7 @@ export default {
|
|||
},
|
||||
intentNode: {
|
||||
label: '意图识别',
|
||||
text: '将用户问题与用户预设的意图分类进行匹配',
|
||||
other: '其他',
|
||||
placeholder: '请选择分类项',
|
||||
classify: {
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ export default {
|
|||
continue: '继续生成',
|
||||
replace: '替换',
|
||||
exit: '确认退出并舍弃 AI 生成的内容吗?',
|
||||
loading: '生成中...',
|
||||
},
|
||||
dialog: {
|
||||
addKnowledge: '添加关联知识库',
|
||||
|
|
|
|||
|
|
@ -322,6 +322,7 @@ export default {
|
|||
},
|
||||
intentNode: {
|
||||
label: '意圖識別',
|
||||
text: '將用戶問題與用戶預設的意圖分類進行匹配',
|
||||
other: '其他',
|
||||
placeholder: '請選擇分類項',
|
||||
classify: {
|
||||
|
|
|
|||
|
|
@ -132,6 +132,7 @@ export default {
|
|||
continue: '繼續生成',
|
||||
replace: '替換',
|
||||
exit: '確認退出並捨棄 AI 生成的內容嗎?',
|
||||
loading: '生成中...',
|
||||
},
|
||||
dialog: {
|
||||
addKnowledge: '新增關聯知識庫',
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
</div>
|
||||
<p v-else-if="loading" shadow="always" style="margin: 0.5rem 0">
|
||||
<el-icon class="is-loading color-primary mr-4"><Loading /></el-icon>
|
||||
{{ $t('chat.tip.answerLoading') }}
|
||||
{{ $t('views.application.generateDialog.loading') }}
|
||||
<span class="dotting"></span>
|
||||
</p>
|
||||
<p v-else class="flex align-center">
|
||||
|
|
@ -33,11 +33,18 @@
|
|||
</p>
|
||||
</el-scrollbar>
|
||||
<div v-if="answer && !loading && !isStreaming && !showContinueButton">
|
||||
<el-button type="primary" @click="() => emit('replace', answer)"> {{ $t('views.application.generateDialog.replace') }} </el-button>
|
||||
<el-button type="primary" @click="() => emit('replace', answer)">
|
||||
{{ $t('views.application.generateDialog.replace') }}
|
||||
</el-button>
|
||||
<el-button @click="reAnswerClick" :disabled="!answer || loading" :loading="loading">
|
||||
{{ $t('views.application.generateDialog.remake') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="mt-8" v-else>
|
||||
<el-button type="primary" v-if="showContinueButton" @click="continueStreaming" link>
|
||||
{{ $t('views.application.generateDialog.continue') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 文本输入框 -->
|
||||
|
|
@ -49,12 +56,7 @@
|
|||
{{ $t('views.application.generateDialog.stop') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-if="showContinueButton" class="text-center mb-8">
|
||||
<el-button class="border-primary video-stop-button" @click="continueStreaming">
|
||||
<app-icon iconName="app-video-stop" class="mr-8"></app-icon>
|
||||
{{ $t('views.application.generateDialog.continue') }}
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<div class="operate-textarea">
|
||||
<el-input
|
||||
ref="quickInputRef"
|
||||
|
|
@ -75,7 +77,11 @@
|
|||
:disabled="!inputValue.trim() || loading || isStreaming"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
<img v-show="!inputValue.trim() || loading || isStreaming" src="@/assets/icon_send.svg" alt="" />
|
||||
<img
|
||||
v-show="!inputValue.trim() || loading || isStreaming"
|
||||
src="@/assets/icon_send.svg"
|
||||
alt=""
|
||||
/>
|
||||
<SendIcon v-show="inputValue.trim() && !loading && !isStreaming" />
|
||||
</el-button>
|
||||
</div>
|
||||
|
|
@ -88,7 +94,7 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onUnmounted,reactive, ref, nextTick, watch } from 'vue'
|
||||
import { computed, onUnmounted, reactive, ref, nextTick, watch } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { MsgConfirm } from '@/utils/message'
|
||||
import { t } from '@/locales'
|
||||
|
|
@ -161,7 +167,6 @@ const currentDisplayIndex = ref<number>(0) // 当前显示到的字符位置
|
|||
let streamTimer: number | null = null // 定时器引用
|
||||
const isOutputComplete = ref<boolean>(false)
|
||||
|
||||
|
||||
// 模拟流式输出的定时器函数
|
||||
const startStreamingOutput = () => {
|
||||
if (streamTimer) {
|
||||
|
|
@ -182,9 +187,9 @@ const startStreamingOutput = () => {
|
|||
if (currentAnswer && currentAnswer.role === 'ai') {
|
||||
currentAnswer.content = fullContent.value.substring(0, currentDisplayIndex.value)
|
||||
}
|
||||
} else if (loading.value === false && currentDisplayIndex.value >= fullContent.value.length) {
|
||||
stopStreaming()
|
||||
}
|
||||
} else if (loading.value === false && currentDisplayIndex.value >= fullContent.value.length) {
|
||||
stopStreaming()
|
||||
}
|
||||
}, 50) // 每50ms输出一次
|
||||
}
|
||||
|
||||
|
|
@ -195,7 +200,7 @@ const stopStreaming = () => {
|
|||
streamTimer = null
|
||||
}
|
||||
isStreaming.value = false
|
||||
isPaused.value = false
|
||||
isPaused.value = false
|
||||
loading.value = false
|
||||
isOutputComplete.value = true
|
||||
}
|
||||
|
|
@ -204,7 +209,6 @@ const showStopButton = computed(() => {
|
|||
return isStreaming.value
|
||||
})
|
||||
|
||||
|
||||
// 暂停流式输出
|
||||
const pauseStreaming = () => {
|
||||
isPaused.value = true
|
||||
|
|
@ -218,7 +222,6 @@ const continueStreaming = () => {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取一个递归函数,处理流式数据
|
||||
* @param chat 每一条对话记录
|
||||
|
|
@ -227,8 +230,8 @@ const continueStreaming = () => {
|
|||
*/
|
||||
const getWrite = (reader: any) => {
|
||||
let tempResult = ''
|
||||
const middleAnswer = reactive({ content: '', role: 'ai' })
|
||||
chatMessages.value.push(middleAnswer )
|
||||
const middleAnswer = reactive({ content: '', role: 'ai' })
|
||||
chatMessages.value.push(middleAnswer)
|
||||
|
||||
// 初始化状态并
|
||||
fullContent.value = ''
|
||||
|
|
@ -245,7 +248,7 @@ const getWrite = (reader: any) => {
|
|||
const write_stream = ({ done, value }: { done: boolean; value: any }) => {
|
||||
try {
|
||||
if (done) {
|
||||
// 流数据接收完成,但定时器继续运行直到显示完所有内容
|
||||
// 流数据接收完成,但定时器继续运行直到显示完所有内容
|
||||
loading.value = false
|
||||
return
|
||||
}
|
||||
|
|
@ -302,10 +305,11 @@ const answer = computed(() => {
|
|||
|
||||
// 按钮状态计算
|
||||
const showContinueButton = computed(() => {
|
||||
return !isStreaming.value && isPaused.value && currentDisplayIndex.value < fullContent.value.length
|
||||
return (
|
||||
!isStreaming.value && isPaused.value && currentDisplayIndex.value < fullContent.value.length
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
function generatePrompt(inputValue: any) {
|
||||
loading.value = true
|
||||
const workspaceId = user.getWorkspaceId() || 'default'
|
||||
|
|
@ -360,12 +364,10 @@ const handleSubmit = (event?: any) => {
|
|||
if (!originalUserInput.value) {
|
||||
originalUserInput.value = inputValue.value
|
||||
}
|
||||
if (inputValue.value) {
|
||||
if (inputValue.value) {
|
||||
generatePrompt(inputValue.value)
|
||||
inputValue.value = ''
|
||||
inputValue.value = ''
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
// 如果同时按下ctrl/shift/cmd/opt +enter,则会换行
|
||||
insertNewlineAtCursor(event)
|
||||
|
|
@ -415,17 +417,12 @@ const handleScroll = () => {
|
|||
}
|
||||
|
||||
const handleDialogClose = (done: () => void) => {
|
||||
|
||||
// 弹出 消息
|
||||
MsgConfirm(
|
||||
t('common.tip'),
|
||||
t('views.application.generateDialog.exit'),
|
||||
{
|
||||
confirmButtonText: t('common.confirm'),
|
||||
cancelButtonText: t('common.cancel'),
|
||||
distinguishCancelAndClose: true,
|
||||
}
|
||||
)
|
||||
MsgConfirm(t('common.tip'), t('views.application.generateDialog.exit'), {
|
||||
confirmButtonText: t('common.confirm'),
|
||||
cancelButtonText: t('common.cancel'),
|
||||
distinguishCancelAndClose: true,
|
||||
})
|
||||
.then(() => {
|
||||
// 点击确认,清除状态
|
||||
stopStreaming()
|
||||
|
|
@ -437,8 +434,7 @@ const handleDialogClose = (done: () => void) => {
|
|||
})
|
||||
.catch(() => {
|
||||
// 点击取消
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
// 组件卸载时清理定时器
|
||||
|
|
|
|||
|
|
@ -362,7 +362,7 @@ export const toolNode = {
|
|||
|
||||
export const intentNode = {
|
||||
type: WorkflowType.IntentNode,
|
||||
text: t('views.applicationWorkflow.nodes.intentNode.label'),
|
||||
text: t('views.applicationWorkflow.nodes.intentNode.text'),
|
||||
label: t('views.applicationWorkflow.nodes.intentNode.label'),
|
||||
height: 260,
|
||||
properties: {
|
||||
|
|
|
|||
Loading…
Reference in New Issue