Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ class ChatNodeSerializer(serializers.Serializer):

image_list = serializers.ListField(required=False, label=_("picture"))

vision = serializers.BooleanField(required=False, default=False, label=_("vision"))


class IChatNode(INode):
type = 'ai-chat-node'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -391,15 +391,21 @@ def get_history_message(history_chat_record, dialogue_number, dialogue_type, run
def generate_prompt_question(self, prompt, model):
image = self.get_image()
video = self.get_video()
vision = self.is_vision()
videos = []
images = []
if image:
if image and vision:
images = self._process_images(image)
if video:
if video and vision:
videos = self._process_videos(video, model)
return HumanMessage(
content=[*videos, *images, {'type': 'text', 'text': self.workflow_manage.generate_prompt(prompt)}])

def is_vision(self):
if 'vision' in self.node_params_serializer.data:
return self.node_params_serializer.data.get('vision')
return False

def get_image(self):
if 'image_list' in self.node_params_serializer.data:
image = self.workflow_manage.get_reference_field(self.node_params_serializer.data.get('image_list')[0],
Expand Down
3 changes: 3 additions & 0 deletions ui/src/locales/lang/en-US/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ export default {
label: 'AI Chat',
text: 'Chat with an AI model',
answer: 'AI Content',
vision: {
label: 'vision',
},
returnContent: {
label: 'Return Content',
tooltip: `If turned off, the content of this node will not be output to the user.
Expand Down
3 changes: 3 additions & 0 deletions ui/src/locales/lang/zh-CN/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ export default {
label: 'AI 对话',
text: '与 AI 大模型进行对话',
answer: 'AI 回答内容',
vision: {
label: '视觉',
},
returnContent: {
label: '返回内容',
tooltip: `关闭后该节点的内容则不输出给用户。
Expand Down
3 changes: 3 additions & 0 deletions ui/src/locales/lang/zh-Hant/workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ export default {
label: 'AI 對話',
text: '與 AI 大模型進行對話',
answer: 'AI 回答內容',
vision: {
label: '視覺',
},
returnContent: {
label: '返回內容',
tooltip: `關閉後該節點的內容則不輸出給用戶。
Expand Down
119 changes: 66 additions & 53 deletions ui/src/workflow/nodes/ai-chat-node/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -170,60 +170,66 @@
:step-strictly="true"
/>
</el-form-item>
<el-form-item
:rules="{
type: 'array',
required: true,
message: $t('workflow.nodes.imageUnderstandNode.image.requiredMessage'),
trigger: 'change',
}"
>
<div class="flex align-center">
<div>
<span>{{ $t('workflow.nodes.imageUnderstandNode.image.label') }} </span>
<div class="flex" style="justify-content: space-between">
{{ t('workflow.nodes.aiChatNode.vision.label') }}
<el-switch size="small" v-model="vision" />
</div>
<template v-if="vision">
<el-form-item
:rules="{
type: 'array',
required: true,
message: $t('workflow.nodes.imageUnderstandNode.image.requiredMessage'),
trigger: 'change',
}"
>
<div class="flex align-center">
<div>
<span>{{ $t('workflow.nodes.imageUnderstandNode.image.label') }} </span>
</div>
<el-tooltip effect="dark" placement="right">
<template #content>
<div style="white-space: pre-wrap; font-family: monospace">{{ fileTooltip }}</div>
</template>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip>
</div>
<el-tooltip effect="dark" placement="right">
<template #content>
<div style="white-space: pre-wrap; font-family: monospace">{{ fileTooltip }}</div>
</template>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip>
</div>
<NodeCascader
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
:placeholder="$t('workflow.nodes.imageUnderstandNode.image.requiredMessage')"
v-model="chat_data.image_list"
/>
</el-form-item>
<el-form-item
:rules="{
type: 'array',
required: false,
message: $t('workflow.nodes.videoUnderstandNode.video.requiredMessage'),
trigger: 'change',
}"
>
<div class="flex align-center">
<div>
<span>{{ $t('workflow.nodes.videoUnderstandNode.video.label') }} </span>
<NodeCascader
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
:placeholder="$t('workflow.nodes.imageUnderstandNode.image.requiredMessage')"
v-model="chat_data.image_list"
/>
</el-form-item>
<el-form-item
:rules="{
type: 'array',
required: false,
message: $t('workflow.nodes.videoUnderstandNode.video.requiredMessage'),
trigger: 'change',
}"
>
<div class="flex align-center">
<div>
<span>{{ $t('workflow.nodes.videoUnderstandNode.video.label') }} </span>
</div>
<el-tooltip effect="dark" placement="right">
<template #content>
<div style="white-space: pre-wrap; font-family: monospace">{{ fileTooltip }}</div>
</template>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip>
</div>
<el-tooltip effect="dark" placement="right">
<template #content>
<div style="white-space: pre-wrap; font-family: monospace">{{ fileTooltip }}</div>
</template>
<AppIcon iconName="app-warning" class="app-warning-icon"></AppIcon>
</el-tooltip>
</div>
<NodeCascader
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
:placeholder="$t('workflow.nodes.videoUnderstandNode.video.requiredMessage')"
v-model="chat_data.video_list"
/>
</el-form-item>
<NodeCascader
ref="nodeCascaderRef"
:nodeModel="nodeModel"
class="w-full"
:placeholder="$t('workflow.nodes.videoUnderstandNode.video.requiredMessage')"
v-model="chat_data.video_list"
/> </el-form-item
></template>

<div class="mb-8 mt-12 flex-between">
<span class="mr-4 lighter">
{{ $t('views.tool.skill.title') }}
Expand Down Expand Up @@ -616,7 +622,14 @@ const route = useRoute()
const {
params: { id },
} = route as any

const vision = computed({
get: () => {
return props.nodeModel.properties.node_data.vision
},
set: (vision: boolean) => {
set(props.nodeModel.properties.node_data, 'vision', vision)
},
})
const apiType = computed(() => {
if (route.path.includes('resource-management')) {
return 'systemManage'
Expand Down
Loading