mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 10:12:51 +00:00
feat: Knowledge write node
This commit is contained in:
parent
399f33604c
commit
39fd3657dd
|
|
@ -18,6 +18,7 @@ from .image_generate_step_node import *
|
|||
from .image_to_video_step_node import BaseImageToVideoNode
|
||||
from .image_understand_step_node import *
|
||||
from .intent_node import *
|
||||
from .knowledge_write_node.impl.base_knowledge_write_node import BaseKnowledgeWriteNode
|
||||
from .loop_break_node import BaseLoopBreakNode
|
||||
from .loop_continue_node import BaseLoopContinueNode
|
||||
from .loop_node import *
|
||||
|
|
@ -49,7 +50,7 @@ node_list = [BaseStartStepNode, BaseChatNode, BaseSearchKnowledgeNode, BaseSearc
|
|||
BaseIntentNode, BaseLoopNode, BaseLoopStartStepNode,
|
||||
BaseLoopContinueNode,
|
||||
BaseLoopBreakNode, BaseVariableSplittingNode, BaseParameterExtractionNode, BaseVariableAggregationNode,
|
||||
BaseDataSourceLocalNode,BaseDataSourceWebNode]
|
||||
BaseDataSourceLocalNode,BaseDataSourceWebNode,BaseKnowledgeWriteNode]
|
||||
|
||||
|
||||
def get_node(node_type):
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
# coding=utf-8
|
||||
"""
|
||||
@project: MaxKB
|
||||
@Author:niu
|
||||
@file: __init__.py.py
|
||||
@date:2025/11/13 11:17
|
||||
@desc:
|
||||
"""
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
# coding=utf-8
|
||||
"""
|
||||
@project: MaxKB
|
||||
@Author:niu
|
||||
@file: i_knowledge_write_node.py
|
||||
@date:2025/11/13 11:19
|
||||
@desc:
|
||||
"""
|
||||
from typing import Type
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from application.flow.i_step_node import INode, NodeResult
|
||||
|
||||
|
||||
|
||||
class KnowledgeWriteNodeParamSerializer(serializers.Serializer):
|
||||
paragraph_list = serializers.ListField(required=True, label=_("Paragraph list"))
|
||||
chunk_length = serializers.CharField(required=True, label=_("Child chunk length"))
|
||||
|
||||
|
||||
|
||||
|
||||
class IKnowledgeWriteNode(INode):
|
||||
|
||||
def get_node_params_serializer_class(self) -> Type[serializers.Serializer]:
|
||||
return KnowledgeWriteNodeParamSerializer
|
||||
|
||||
|
||||
def _run(self):
|
||||
return self.execute(**self.node_params_serializer.data, **self.flow_params_serializer.data)
|
||||
|
||||
def execute(self, paragraph_list, chunk_length, **kwargs) -> NodeResult:
|
||||
pass
|
||||
|
||||
type = 'knowledge-write-node'
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
# coding=utf-8
|
||||
"""
|
||||
@project: MaxKB
|
||||
@Author:niu
|
||||
@file: __init__.py.py
|
||||
@date:2025/11/13 11:18
|
||||
@desc:
|
||||
"""
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# coding=utf-8
|
||||
"""
|
||||
@project: MaxKB
|
||||
@Author:niu
|
||||
@file: base_knowledge_write_node.py
|
||||
@date:2025/11/13 11:19
|
||||
@desc:
|
||||
"""
|
||||
from application.flow.i_step_node import NodeResult
|
||||
from application.flow.step_node.knowledge_write_node.i_knowledge_write_node import IKnowledgeWriteNode
|
||||
|
||||
|
||||
class BaseKnowledgeWriteNode(IKnowledgeWriteNode):
|
||||
|
||||
def save_context(self, details, workflow_manage):
|
||||
pass
|
||||
|
||||
def execute(self, paragraph_list, chunk_length, **kwargs) -> NodeResult:
|
||||
pass
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 10C0 5.28595 0 2.92893 1.46447 1.46447C2.92893 0 5.28595 0 10 0C14.714 0 17.0711 0 18.5355 1.46447C20 2.92893 20 5.28595 20 10C20 14.714 20 17.0711 18.5355 18.5355C17.0711 20 14.714 20 10 20C5.28595 20 2.92893 20 1.46447 18.5355C0 17.0711 0 14.714 0 10Z" fill="#3370FF"/>
|
||||
<path d="M6.91961 15.7292H5.31258C5.17445 15.7292 5.04197 15.6743 4.9443 15.5767C4.84662 15.479 4.79175 15.3465 4.79175 15.2084V4.79171C4.79175 4.65357 4.84662 4.5211 4.9443 4.42342C5.04197 4.32575 5.17445 4.27087 5.31258 4.27087H13.6459C13.784 4.27087 13.9165 4.32575 14.0142 4.42342C14.1119 4.5211 14.1667 4.65357 14.1667 4.79171V8.48155C14.1668 8.61964 14.112 8.75208 14.0144 8.84978L7.2881 15.5766C7.23972 15.625 7.18227 15.6634 7.11904 15.6896C7.05582 15.7158 6.98805 15.7292 6.91961 15.7292ZM7.21177 9.92377C7.26061 9.9726 7.32685 10 7.39591 10H10.0001C10.0691 10 10.1354 9.9726 10.1842 9.92377C10.2331 9.87493 10.2605 9.80869 10.2605 9.73962V9.21879C10.2605 9.14972 10.2331 9.08349 10.1842 9.03465C10.1354 8.98581 10.0691 8.95837 10.0001 8.95837H7.39591C7.32685 8.95837 7.26061 8.98581 7.21177 9.03465C7.16293 9.08349 7.1355 9.14972 7.1355 9.21879V9.73962C7.1355 9.80869 7.16293 9.87493 7.21177 9.92377ZM7.21177 7.3196C7.26061 7.36844 7.32685 7.39587 7.39591 7.39587H11.823C11.8572 7.39587 11.8911 7.38914 11.9227 7.37605C11.9542 7.36296 11.983 7.34378 12.0071 7.3196C12.0313 7.29542 12.0505 7.26671 12.0636 7.23511C12.0767 7.20352 12.0834 7.16966 12.0834 7.13546V6.61462C12.0834 6.58043 12.0767 6.54656 12.0636 6.51497C12.0505 6.48337 12.0313 6.45466 12.0071 6.43048C11.983 6.4063 11.9542 6.38712 11.9227 6.37403C11.8911 6.36094 11.8572 6.35421 11.823 6.35421H7.39591C7.32685 6.35421 7.26061 6.38164 7.21177 6.43048C7.16293 6.47932 7.1355 6.54556 7.1355 6.61462V7.13546C7.1355 7.20452 7.16293 7.27076 7.21177 7.3196Z" fill="white"/>
|
||||
<path d="M14.3477 12.7485L12.8787 11.2798L9.65087 14.5282L9.47925 15.9201C9.47925 15.9892 9.50668 16.0554 9.55552 16.1042C9.60436 16.1531 9.6706 16.1805 9.73966 16.1805L11.1334 15.9587L14.3477 12.7485Z" fill="white"/>
|
||||
<path d="M14.7255 10.1635C14.5224 9.96007 14.2086 9.94445 14.0242 10.1283L13.2456 10.9096L14.7164 12.3803L15.4958 11.6022L15.5205 11.5756C15.6789 11.3892 15.656 11.0939 15.462 10.8996L14.7255 10.1635Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
|
|
@ -40,6 +40,7 @@ export enum WorkflowType {
|
|||
ParameterExtractionNode = 'parameter-extraction-node',
|
||||
DataSourceLocalNode = 'data-source-local-node',
|
||||
DataSourceWebNode = 'data-source-web-node',
|
||||
KnowledgeWriteNode = 'knowledge-write-node',
|
||||
}
|
||||
export enum WorkflowKind {
|
||||
DataSource = 'data-source',
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ export default {
|
|||
},
|
||||
aggregationStrategy: 'Aggregation Strategy',
|
||||
inputPlaceholder: 'Please input',
|
||||
inputContent: 'Input content',
|
||||
selectPlaceholder: 'Please select',
|
||||
title: 'Title',
|
||||
content: 'Content',
|
||||
|
|
|
|||
|
|
@ -79,6 +79,11 @@ export default {
|
|||
loopNodeBreakNodeRequired: 'Wireless loop must have a Break node',
|
||||
},
|
||||
nodes: {
|
||||
knowledgeWriteNode: {
|
||||
chunk_length: 'Chunk length',
|
||||
text: 'Knowledge write',
|
||||
label: 'Knowledge write',
|
||||
},
|
||||
dataSourceWebNode: {
|
||||
label: 'Web Site',
|
||||
text: 'Web Site',
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ export default {
|
|||
},
|
||||
aggregationStrategy: '聚合策略',
|
||||
inputPlaceholder: '请输入',
|
||||
inputContent: '输入内容',
|
||||
selectPlaceholder: '请选择',
|
||||
title: '标题',
|
||||
content: '内容',
|
||||
|
|
|
|||
|
|
@ -81,6 +81,11 @@ export default {
|
|||
loopNodeBreakNodeRequired: '无限循环 必须存在 Break 节点',
|
||||
},
|
||||
nodes: {
|
||||
knowledgeWriteNode: {
|
||||
chunk_length: '子分块长度',
|
||||
text: '知识库写入',
|
||||
label: '知识库写入',
|
||||
},
|
||||
dataSourceWebNode: {
|
||||
label: 'Web站点',
|
||||
text: 'Web站点',
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ export default {
|
|||
},
|
||||
aggregationStrategy: '聚合策略',
|
||||
inputPlaceholder: '請輸入',
|
||||
inputContent: '輸入內容',
|
||||
selectPlaceholder: '請選擇',
|
||||
title: '標題',
|
||||
content: '内容',
|
||||
|
|
|
|||
|
|
@ -80,6 +80,11 @@ export default {
|
|||
loopNodeBreakNodeRequired: '無限循環必須存在Break節點',
|
||||
},
|
||||
nodes: {
|
||||
knowledgeWriteNode: {
|
||||
chunk_length: '子分塊長度',
|
||||
text: '知識庫寫入',
|
||||
label: '知識庫寫入',
|
||||
},
|
||||
dataSourceWebNode: {
|
||||
label: 'Web網站',
|
||||
text: 'Web網站',
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ const systemManage = {
|
|||
PermissionConst.RESOURCE_KNOWLEDGE_TAG_DELETE
|
||||
],'OR'
|
||||
),
|
||||
bug: () =>
|
||||
debug: () =>
|
||||
hasPermission([
|
||||
RoleConst.ADMIN,
|
||||
PermissionConst.RESOURCE_KNOWLEDGE_WORKFLOW_READ
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
<AppIcon iconName="app-add-outlined" class="mr-4" />
|
||||
{{ $t('views.knowledgeWorkflow.setting.addComponent') }}
|
||||
</el-button>
|
||||
<el-button @click="clickShowDebug" :disabled="showDebug">
|
||||
<el-button @click="clickShowDebug" :disabled="showDebug" v-if="permissionPrecise.debug(id)">
|
||||
<AppIcon iconName="app-debug-outlined" class="mr-4"></AppIcon>
|
||||
{{ $t('views.knowledgeWorkflow.setting.debug') }}
|
||||
</el-button>
|
||||
|
|
|
|||
|
|
@ -119,7 +119,19 @@ export const dataSourceWebNode = {
|
|||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export const knowledgeWriteNode = {
|
||||
type: WorkflowType.KnowledgeWriteNode,
|
||||
text: t('views.applicationWorkflow.nodes.knowledgeWriteNode.text'),
|
||||
label: t('views.applicationWorkflow.nodes.knowledgeWriteNode.label'),
|
||||
properties: {
|
||||
height: 252,
|
||||
stepName: t('views.applicationWorkflow.nodes.knowledgeWriteNode.label'),
|
||||
config: {
|
||||
fields:[]
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -706,7 +718,7 @@ export const knowledgeMenuNodes = [
|
|||
},
|
||||
{
|
||||
label: t('views.knowledge.title'),
|
||||
list: [documentExtractNode],
|
||||
list: [documentExtractNode, knowledgeWriteNode],
|
||||
},
|
||||
{
|
||||
label: t('views.applicationWorkflow.nodes.classify.businessLogic'),
|
||||
|
|
@ -952,6 +964,7 @@ export const nodeDict: any = {
|
|||
[WorkflowType.KnowledgeBase]: knowledgeBaseNode,
|
||||
[WorkflowType.DataSourceLocalNode]: dataSourceLocalNode,
|
||||
[WorkflowType.DataSourceWebNode]: dataSourceWebNode,
|
||||
[WorkflowType.KnowledgeWriteNode]: knowledgeWriteNode,
|
||||
}
|
||||
|
||||
export function isWorkFlow(type: string | undefined) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
<template>
|
||||
<el-avatar shape="square">
|
||||
<img src="@/assets/workflow/icon_knowledge_write.svg" style="width: 75%" alt="" />
|
||||
</el-avatar>
|
||||
</template>
|
||||
<script setup lang="ts"></script>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import KnowledgeWriteVue from './index.vue'
|
||||
import { AppNode, AppNodeModel } from '@/workflow/common/app-node'
|
||||
|
||||
|
||||
class KnowledgeWriteNode extends AppNode {
|
||||
constructor(props: any) {
|
||||
super(props, KnowledgeWriteVue)
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
type: 'knowledge-write-node',
|
||||
model: AppNodeModel,
|
||||
view: KnowledgeWriteNode,
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
<template>
|
||||
<NodeContainer :nodeModel="nodeModel">
|
||||
<h5 class="title-decoration-1 mb-8">{{ $t('views.applicationWorkflow.nodeSetting') }}</h5>
|
||||
<el-card shadow="never" class="card-never">
|
||||
<el-form
|
||||
@submit.prevent
|
||||
:model="form_data"
|
||||
label-position="top"
|
||||
require-asterisk-position="right"
|
||||
label-width="auto"
|
||||
ref="IntentClassifyNodeFormRef"
|
||||
hide-required-asterisk
|
||||
>
|
||||
<el-form-item
|
||||
prop="paragraph_list"
|
||||
:label="$t('common.inputContent')"
|
||||
:rules="{
|
||||
message: $t('views.applicationWorkflow.nodes.textToSpeechNode.content.label'),
|
||||
trigger: 'change',
|
||||
required: true,
|
||||
}"
|
||||
>
|
||||
<template #label>
|
||||
<div class="flex-between">
|
||||
<div>
|
||||
<span
|
||||
>{{ $t('common.inputContent')
|
||||
}}<span class="color-danger">*</span></span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<NodeCascader
|
||||
ref="nodeCascaderRef"
|
||||
:nodeModel="nodeModel"
|
||||
class="w-full"
|
||||
:placeholder="$t('views.applicationWorkflow.nodes.textToSpeechNode.content.label')"
|
||||
v-model="form_data.paragraph_list"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
prop="chunk_length"
|
||||
:label="$t('views.applicationWorkflow.nodes.knowledgeWriteNode.chunk_length')"
|
||||
:rules="{
|
||||
message: $t('views.applicationWorkflow.nodes.knowledgeWriteNode.chunk_length'),
|
||||
trigger: 'change',
|
||||
required: true,
|
||||
}"
|
||||
>
|
||||
<template #label>
|
||||
<div class="flex-between">
|
||||
<div>
|
||||
<span
|
||||
>{{ $t('views.applicationWorkflow.nodes.knowledgeWriteNode.chunk_length')
|
||||
}}<span class="color-danger">*</span></span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<el-slider v-model="form_data.chunk_length" show-input :max="8192"></el-slider>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</NodeContainer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import NodeContainer from '@/workflow/common/NodeContainer.vue'
|
||||
import { computed } from 'vue'
|
||||
import { set } from 'lodash'
|
||||
import NodeCascader from '@/workflow/common/NodeCascader.vue'
|
||||
|
||||
const props = defineProps<{ nodeModel: any }>()
|
||||
|
||||
const form = {
|
||||
paragraph_list: [],
|
||||
chunk_length: 4096
|
||||
}
|
||||
|
||||
const form_data = computed({
|
||||
get: () => {
|
||||
if (props.nodeModel.properties.node_data) {
|
||||
return props.nodeModel.properties.node_data
|
||||
} else {
|
||||
set(props.nodeModel.properties, 'node_data', form)
|
||||
}
|
||||
return props.nodeModel.properties.node_data
|
||||
},
|
||||
set: (value) => {
|
||||
set(props.nodeModel.properties, 'node_data', value)
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
Loading…
Reference in New Issue