feat: Consciousness recognition node

This commit is contained in:
wangdan-fit2cloud 2025-09-18 14:55:03 +08:00
parent 16ade76446
commit 7af880f1db
9 changed files with 42 additions and 40 deletions

View File

@ -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">

View File

@ -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: {

View File

@ -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',

View File

@ -329,6 +329,7 @@ export default {
},
intentNode: {
label: '意图识别',
text: '将用户问题与用户预设的意图分类进行匹配',
other: '其他',
placeholder: '请选择分类项',
classify: {

View File

@ -133,6 +133,7 @@ export default {
continue: '继续生成',
replace: '替换',
exit: '确认退出并舍弃 AI 生成的内容吗?',
loading: '生成中...',
},
dialog: {
addKnowledge: '添加关联知识库',

View File

@ -322,6 +322,7 @@ export default {
},
intentNode: {
label: '意圖識別',
text: '將用戶問題與用戶預設的意圖分類進行匹配',
other: '其他',
placeholder: '請選擇分類項',
classify: {

View File

@ -132,6 +132,7 @@ export default {
continue: '繼續生成',
replace: '替換',
exit: '確認退出並捨棄 AI 生成的內容嗎?',
loading: '生成中...',
},
dialog: {
addKnowledge: '新增關聯知識庫',

View File

@ -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(() => {
//
}
)
})
}
//

View File

@ -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: {