|
|
@@ -5,7 +5,11 @@
|
|
|
</div>
|
|
|
<div
|
|
|
class="flex flex-1 flex-col overflow-hidden"
|
|
|
- :class="item.slot ? '' : 'max-w-fit'"
|
|
|
+ :class="
|
|
|
+ (item.slot ? '' : 'max-w-fit') +
|
|
|
+ ' ' +
|
|
|
+ (item.workflows?.length > 0 ? 'w-full max-w-full' : '')
|
|
|
+ "
|
|
|
>
|
|
|
<template v-if="item.prologue">
|
|
|
<div
|
|
|
@@ -52,13 +56,138 @@
|
|
|
</template>
|
|
|
<template v-else>
|
|
|
<div
|
|
|
- class="w-fit max-w-full rounded-lg rounded-tl-none bg-[#EAF1FF] p-2.75 text-[#303133]"
|
|
|
+ class="max-w-full rounded-lg rounded-tl-none bg-[#EAF1FF] p-2.75 text-[#303133]"
|
|
|
+ :class="item.workflows?.length > 0 ? 'w-full' : 'w-fit'"
|
|
|
>
|
|
|
<template v-for="part in textCpt">
|
|
|
<template v-if="part.type === 'think'">
|
|
|
<thinkCom :text="part.text" />
|
|
|
</template>
|
|
|
<template v-else>
|
|
|
+ <template v-if="item.workflows?.length > 0">
|
|
|
+ <div
|
|
|
+ class="flex flex-col rounded-sm p-2 text-xs"
|
|
|
+ :class="
|
|
|
+ item.workflowStatus === 'succeeded'
|
|
|
+ ? 'bg-[var(--czr-success-color)]/15'
|
|
|
+ : item.workflowStatus === 'failed'
|
|
|
+ ? 'bg-[var(--czr-error-color)]/15'
|
|
|
+ : 'bg-[#ffffff]/50'
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ class="__hover flex items-center"
|
|
|
+ @click="state.workflowExpend = !state.workflowExpend"
|
|
|
+ >
|
|
|
+ <template v-if="item.workflowStatus === 'succeeded'">
|
|
|
+ <SvgIcon
|
|
|
+ name="success"
|
|
|
+ size="14"
|
|
|
+ color="var(--czr-success-color)"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ <template v-else-if="item.workflowStatus === 'failed'">
|
|
|
+ <SvgIcon
|
|
|
+ name="failed"
|
|
|
+ size="14"
|
|
|
+ color="var(--czr-error-color)"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <SvgIcon name="wait" size="14" />
|
|
|
+ </template>
|
|
|
+ <div class="ml-0.5">工作流</div>
|
|
|
+ <template v-if="state.workflowExpend">
|
|
|
+ <SvgIcon
|
|
|
+ name="czr_arrow"
|
|
|
+ size="8"
|
|
|
+ rotate="90"
|
|
|
+ class="ml-auto"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <SvgIcon name="czr_arrow" size="8" class="ml-1" />
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ <div class="mt-2 flex flex-col gap-1">
|
|
|
+ <template v-for="wf in item.workflows">
|
|
|
+ <div class="rounded-sm bg-[#ffffff] p-1">
|
|
|
+ <div
|
|
|
+ class="flex items-center"
|
|
|
+ :class="wf.status ? '__hover' : 'cursor-no-drop'"
|
|
|
+ @click="
|
|
|
+ wf.status ? (wf.__expend = !wf.__expend) : undefined
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <template v-if="wf.__expend">
|
|
|
+ <SvgIcon name="czr_arrow" size="8" rotate="90" />
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <SvgIcon name="czr_arrow" size="8" />
|
|
|
+ </template>
|
|
|
+ <img
|
|
|
+ :src="nodeSources[wf.nodeType].icon"
|
|
|
+ class="ml-1 size-4"
|
|
|
+ />
|
|
|
+ <div class="ml-0.5 flex-1 font-bold" v-title>
|
|
|
+ {{ wf.title }}
|
|
|
+ </div>
|
|
|
+ <div class="ml-auto flex items-center">
|
|
|
+ <template v-if="wf.status === 'succeeded'">
|
|
|
+ <SvgIcon
|
|
|
+ name="success"
|
|
|
+ size="12"
|
|
|
+ color="var(--czr-success-color)"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ <template v-else-if="wf.status === 'failed'">
|
|
|
+ <SvgIcon
|
|
|
+ name="failed"
|
|
|
+ size="12"
|
|
|
+ color="var(--czr-error-color)"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <div class="mr-1 text-[var(--czr-main-color)]/70">
|
|
|
+ Running
|
|
|
+ </div>
|
|
|
+ <SvgIcon name="wait" size="12" />
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-if="wf.__expend"
|
|
|
+ class="mt-1 flex flex-col gap-1"
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ v-if="wf.error"
|
|
|
+ class="rounded-sm border-1 border-[var(--czr-error-color)] p-1 text-[var(--czr-error-color)] shadow"
|
|
|
+ >
|
|
|
+ <div>错误信息</div>
|
|
|
+ <div class="mt-1 break-words">
|
|
|
+ {{ wf.error }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-if="wf.inputData"
|
|
|
+ class="rounded-sm border-1 border-[#000000]/5 p-1 shadow"
|
|
|
+ >
|
|
|
+ <div>输入</div>
|
|
|
+ <div class="mt-1">{{ wf.inputData }}</div>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-if="wf.outputData"
|
|
|
+ class="rounded-sm border-1 border-[#000000]/5 p-1 shadow"
|
|
|
+ >
|
|
|
+ <div>输出</div>
|
|
|
+ <div class="mt-1">{{ wf.outputData }}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
<div
|
|
|
class="answer-markdown"
|
|
|
:class="{ error: item.error }"
|
|
|
@@ -176,6 +305,7 @@ import thinkCom from './think.vue'
|
|
|
import { copy } from '@/utils/czr-util'
|
|
|
import { ElMessage } from 'element-plus'
|
|
|
import useTextToSpeech from '../audio/useTextToSpeech'
|
|
|
+import { nodeSources } from '@/views/workflow/config'
|
|
|
|
|
|
const { speak, stop } = useTextToSpeech()
|
|
|
const md = new MarkdownIt({
|
|
|
@@ -195,7 +325,9 @@ const props = defineProps({
|
|
|
goodMap: {} as any,
|
|
|
badMap: {} as any,
|
|
|
})
|
|
|
-const state: any = reactive({})
|
|
|
+const state: any = reactive({
|
|
|
+ workflowExpend: false,
|
|
|
+})
|
|
|
const textCpt = computed(() => {
|
|
|
const segments: any = []
|
|
|
const rawContent = props.item.text
|