feat: Workflow menu that distinguishes between applications and knowledge bases

This commit is contained in:
shaohuzhang1 2025-11-24 17:11:20 +08:00
parent 1622d0674f
commit c9eb84ff75
15 changed files with 54 additions and 16 deletions

View File

@ -181,7 +181,7 @@ class Workflow:
return [en.node for en in self.next_node_map.get(node_id, [])]
@staticmethod
def new_instance(flow_obj: Dict, workflow_mode: WorkflowMode = WorkflowMode.APPLICATION.value):
def new_instance(flow_obj: Dict, workflow_mode: WorkflowMode = WorkflowMode.APPLICATION):
nodes = flow_obj.get('nodes')
edges = flow_obj.get('edges')
nodes = [Node(node.get('id'), node.get('type'), **node)

View File

@ -79,7 +79,7 @@ class WorkFlowPostHandler:
message_tokens=message_tokens,
answer_tokens=answer_tokens,
answer_text_list=answer_text_list,
run_time=time.time() - workflow.context['start_time'],
run_time=time.time() - workflow.context.get('start_time') if workflow.context.get('start_time') is not None else 0,
index=0)
self.chat_info.append_chat_record(chat_record)

View File

@ -0,0 +1,26 @@
<template>
<component :is="kw[workflow_mode]" :show="show" :id="id" :workflow-ref="workflowRef"></component>
</template>
<script setup lang="ts">
import { inject } from 'vue'
import { WorkflowMode } from '@/enums/application'
import ApplicationDropdownMenu from '@/components/dropdown_menu/application/index.vue'
import KnowledgeDropdownMenu from '@/components/dropdown_menu/knowledge/index.vue'
const workflow_mode = inject('workflowMode') || WorkflowMode.Application
defineProps({
show: {
type: Boolean,
default: false,
},
id: {
type: String,
default: '',
},
workflowRef: Object,
})
const kw: any = {
[WorkflowMode.Application]: ApplicationDropdownMenu,
[WorkflowMode.Knowledge]: KnowledgeDropdownMenu,
}
</script>
<style lang="scss" scoped></style>

View File

@ -145,7 +145,7 @@ import { ref, onMounted, onBeforeUnmount, computed, nextTick, provide } from 'vu
import { useRouter, useRoute } from 'vue-router'
import type { Action } from 'element-plus'
import Workflow from '@/workflow/index.vue'
import DropdownMenu from '@/views/application-workflow/component/DropdownMenu.vue'
import DropdownMenu from '@/components/dropdown_menu/index.vue'
import PublishHistory from '@/views/application-workflow/component/PublishHistory.vue'
import { isAppIcon, resetUrl } from '@/utils/common'
import { MsgSuccess, MsgError, MsgConfirm } from '@/utils/message'

View File

@ -142,7 +142,7 @@ import { ref, onBeforeMount, onBeforeUnmount, computed, nextTick, provide } from
import { useRouter, useRoute } from 'vue-router'
import type { Action } from 'element-plus'
import Workflow from '@/workflow/index.vue'
import DropdownMenu from '@/views/knowledge-workflow/component/DropdownMenu.vue'
import DropdownMenu from '@/components/dropdown_menu/index.vue'
import PublishHistory from '@/views/knowledge-workflow/component/PublishHistory.vue'
import { isAppIcon, resetUrl } from '@/utils/common'
import { MsgSuccess, MsgError, MsgConfirm } from '@/utils/message'
@ -395,7 +395,6 @@ const clickShowDebug = () => {
}
DebugRef.value?.open(graphData, id)
} catch (e: any) {
console.log(e)
MsgError(e.toString())
}
})

View File

@ -172,8 +172,7 @@
</div>
</template>
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import DropdownMenu from '@/views/application-workflow/component/DropdownMenu.vue'
import { ref, computed, onMounted, inject } from 'vue'
import { set } from 'lodash'
import { iconComponent } from '../icons/utils'
import { copyClick } from '@/utils/clipboard'
@ -182,6 +181,9 @@ import { MsgError, MsgConfirm } from '@/utils/message'
import type { FormInstance } from 'element-plus'
import { t } from '@/locales'
import { useRoute } from 'vue-router'
import DropdownMenu from '@/components/dropdown_menu/index.vue'
const w = inject('workflowMode')
console.log(w)
const route = useRoute()
const {
params: { id },

View File

@ -750,7 +750,7 @@ export const knowledgeMenuNodes = [
},
{
label: t('views.applicationWorkflow.nodes.classify.businessLogic'),
list: [conditionNode, formNode, replyNode, loopNode],
list: [conditionNode, replyNode, loopNode],
},
{
label: t('views.applicationWorkflow.nodes.classify.dataProcessing'),
@ -785,7 +785,14 @@ export const menuNodes = [
},
{
label: t('views.knowledge.title'),
list: [searchKnowledgeNode, searchDocumentNode, rerankerNode, documentExtractNode, documentSplitNode, knowledgeWriteNode],
list: [
searchKnowledgeNode,
searchDocumentNode,
rerankerNode,
documentExtractNode,
documentSplitNode,
knowledgeWriteNode,
],
},
{
label: t('views.applicationWorkflow.nodes.classify.businessLogic'),
@ -865,7 +872,7 @@ export const knowledgeLoopMenuNodes = [
},
{
label: t('views.applicationWorkflow.nodes.classify.businessLogic'),
list: [conditionNode, formNode, replyNode, loopContinueNode, loopBreakNode],
list: [conditionNode, replyNode, loopContinueNode, loopBreakNode],
},
{
label: t('views.applicationWorkflow.nodes.classify.dataProcessing', '数据处理'),

View File

@ -43,7 +43,7 @@ const loop_end_nodes: Array<string> = [
]
const end_nodes_dict = {
[WorkflowMode.Application]: end_nodes,
[WorkflowMode.Knowledge]: end_nodes,
[WorkflowMode.Knowledge]: [WorkflowType.KnowledgeWriteNode],
[WorkflowMode.ApplicationLoop]: loop_end_nodes,
[WorkflowMode.KnowledgeLoop]: loop_end_nodes,
}

View File

@ -6,7 +6,7 @@
</template>
<script setup lang="ts">
import LogicFlow from '@logicflow/core'
import { ref, onMounted, onUnmounted } from 'vue'
import { ref, onMounted, onUnmounted, inject } from 'vue'
import AppEdge from './common/edge'
import loopEdge from './common/loopEdge'
import Control from './common/NodeControl.vue'
@ -18,6 +18,8 @@ import Dagre from '@/workflow/plugins/dagre'
import { disconnectAll, getTeleport } from '@/workflow/common/teleport'
import { WorkflowMode } from '@/enums/application'
const nodes: any = import.meta.glob('./nodes/**/index.ts', { eager: true })
const workflow_mode = inject('workflowMode') || WorkflowMode.Application
const loop_workflow_mode = inject('loopWorkflowMode') || WorkflowMode.ApplicationLoop
defineOptions({ name: 'WorkFlow' })
const TeleportContainer = getTeleport()
@ -95,7 +97,8 @@ const renderGraphData = (data?: any) => {
return {
getNode: () => node,
getGraph: () => graph,
workflowMode: WorkflowMode.Application,
workflowMode: workflow_mode,
loopWorkflowMode: loop_workflow_mode,
}
}
lf.value.graphModel.eventCenter.on('delete_edge', (id_list: Array<string>) => {

View File

@ -17,7 +17,7 @@ class BaseModel extends AppNodeModel {
}
export default {
type: 'knowledge-base-node',
type: 'base-node',
model: BaseModel,
view: BaseNode,
}

View File

@ -6,7 +6,7 @@
<script setup lang="ts">
import { set, cloneDeep } from 'lodash'
import AppEdge from '@/workflow/common/edge'
import { ref, onMounted, onUnmounted } from 'vue'
import { ref, onMounted, onUnmounted, inject } from 'vue'
import LogicFlow from '@logicflow/core'
import Dagre from '@/workflow/plugins/dagre'
import { initDefaultShortcut } from '@/workflow/common/shortcut'
@ -15,6 +15,7 @@ import { WorkflowMode } from '@/enums/application'
import { WorkFlowInstance } from '@/workflow/common/validate'
import { t } from '@/locales'
import { disconnectByFlow } from '@/workflow/common/teleport'
const loop_workflow_mode = inject('loopWorkflowMode') || WorkflowMode.ApplicationLoop
const nodes: any = import.meta.glob('@/workflow/nodes/**/index.ts', { eager: true })
const props = defineProps<{ nodeModel: any }>()
const containerRef = ref()
@ -125,7 +126,7 @@ const renderGraphData = (data?: any) => {
return {
getNode: () => node,
getGraph: () => graph,
workflowMode: WorkflowMode.ApplicationLoop,
workflowMode: loop_workflow_mode,
}
}
lf.value.graphModel.refresh_loop_fields = refresh_loop_fields