diff --git a/README.md b/README.md index 9556afe31..f75c49dee 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ MaxKB = Max Knowledge Base, it is a chatbot based on Large Language Models (LLM) - **Flexible Orchestration**: Equipped with a powerful workflow engine and function library, enabling the orchestration of AI processes to meet the needs of complex business scenarios. - **Seamless Integration**: Facilitates zero-coding rapid integration into third-party business systems, quickly equipping existing systems with intelligent Q&A capabilities to enhance user satisfaction. - **Model-Agnostic**: Supports various large models, including private models (such as DeepSeek, Llama, Qwen, etc.) and public models (like OpenAI, Claude, Gemini, etc.). +- **Multi Modal**: Native support for input and output text, image, audio and video. ## Quick start diff --git a/apps/application/chat_pipeline/step/chat_step/impl/base_chat_step.py b/apps/application/chat_pipeline/step/chat_step/impl/base_chat_step.py index 7fa4f249a..7395240b1 100644 --- a/apps/application/chat_pipeline/step/chat_step/impl/base_chat_step.py +++ b/apps/application/chat_pipeline/step/chat_step/impl/base_chat_step.py @@ -307,7 +307,11 @@ class BaseChatStep(IChatStep): return manage.get_base_to_response().to_block_response(str(chat_id), str(chat_record_id), content, True, request_token, response_token, - {'reasoning_content': reasoning_content}) + {'reasoning_content': reasoning_content, + 'answer_list': [{ + 'content': content, + 'reasoning_content': reasoning_content + }]}) except Exception as e: all_text = 'Exception:' + str(e) write_context(self, manage, 0, 0, all_text) diff --git a/apps/application/flow/workflow_manage.py b/apps/application/flow/workflow_manage.py index d6bb43bf6..cb3f61e22 100644 --- a/apps/application/flow/workflow_manage.py +++ b/apps/application/flow/workflow_manage.py @@ -337,13 +337,15 @@ class WorkflowManage: answer_text = '\n\n'.join( '\n\n'.join([a.get('content') for a in answer]) for answer in answer_text_list) + answer_list = reduce(lambda pre, _n: [*pre, *_n], answer_text_list, []) self.work_flow_post_handler.handler(self.params['chat_id'], self.params['chat_record_id'], answer_text, self) return self.base_to_response.to_block_response(self.params['chat_id'], self.params['chat_record_id'], answer_text, True , message_tokens, answer_tokens, - _status=status.HTTP_200_OK if self.status == 200 else status.HTTP_500_INTERNAL_SERVER_ERROR) + _status=status.HTTP_200_OK if self.status == 200 else status.HTTP_500_INTERNAL_SERVER_ERROR, + other_params={'answer_list': answer_list}) def run_stream(self, current_node, node_result_future, language='zh'): """ diff --git a/apps/common/util/test.py b/apps/common/util/test.py index 00a267c6a..bfcab42d4 100644 --- a/apps/common/util/test.py +++ b/apps/common/util/test.py @@ -13,7 +13,7 @@ from django.core import signing from django.core.cache import cache # alg使用的算法 -HEADER = {'typ': 'JWP', 'alg': 'default'} +HEADER = {'type': 'JWP', 'alg': 'default'} TOKEN_KEY = 'solomon_world_token' TOKEN_SALT = 'solomonwanc@gmail.com' TIME_OUT = 30 * 60 diff --git a/apps/function_lib/serializers/function_lib_serializer.py b/apps/function_lib/serializers/function_lib_serializer.py index 6c658ab81..cccdfcdc3 100644 --- a/apps/function_lib/serializers/function_lib_serializer.py +++ b/apps/function_lib/serializers/function_lib_serializer.py @@ -249,7 +249,7 @@ class FunctionLibSerializer(serializers.Serializer): mk_instance = FlibInstance(application_dict, 'v1') application_pickle = pickle.dumps(mk_instance) response = HttpResponse(content_type='text/plain', content=application_pickle) - response['Content-Disposition'] = f'attachment; filename="{function_lib.name}.flib"' + response['Content-Disposition'] = f'attachment; filename="{function_lib.name}.fx"' return response except Exception as e: return result.error(str(e), response_status=status.HTTP_500_INTERNAL_SERVER_ERROR) diff --git a/ui/src/api/function-lib.ts b/ui/src/api/function-lib.ts index f9082a308..41a90a96c 100644 --- a/ui/src/api/function-lib.ts +++ b/ui/src/api/function-lib.ts @@ -105,7 +105,7 @@ const exportFunctionLib = ( loading?: Ref ) => { return exportFile( - name + '.flib', + name + '.fx', `${prefix}/${id}/export`, undefined, loading diff --git a/ui/src/components/codemirror-editor/index.vue b/ui/src/components/codemirror-editor/index.vue index c4086b872..0d9d81cac 100644 --- a/ui/src/components/codemirror-editor/index.vue +++ b/ui/src/components/codemirror-editor/index.vue @@ -1,16 +1,50 @@ - + diff --git a/ui/src/views/document/index.vue b/ui/src/views/document/index.vue index 626282f36..35692236b 100644 --- a/ui/src/views/document/index.vue +++ b/ui/src/views/document/index.vue @@ -440,7 +440,7 @@ - +
diff --git a/ui/src/views/function-lib/component/FunctionFormDrawer.vue b/ui/src/views/function-lib/component/FunctionFormDrawer.vue index 2b74e052b..2b8031e8c 100644 --- a/ui/src/views/function-lib/component/FunctionFormDrawer.vue +++ b/ui/src/views/function-lib/component/FunctionFormDrawer.vue @@ -133,13 +133,8 @@ -
- - +
+

{{ $t('common.param.outputParam') }} @@ -162,27 +157,6 @@

- - - - - @@ -223,9 +197,6 @@ const form = ref({ permission_type: 'PRIVATE' }) -const dialogVisible = ref(false) -const cloneContent = ref('') - watch(visible, (bool) => { if (!bool) { isEdit.value = false @@ -259,14 +230,8 @@ const rules = reactive({ ] }) -function openCodemirrorDialog() { - cloneContent.value = form.value.code - dialogVisible.value = true -} - -function submitDialog() { - form.value.code = cloneContent.value - dialogVisible.value = false +function submitCodemirrorEditor(val: string) { + form.value.code = val } function close() { @@ -353,13 +318,4 @@ defineExpose({ open }) - + diff --git a/ui/src/workflow/icons/variable-assign-node-icon.vue b/ui/src/workflow/icons/variable-assign-node-icon.vue index d83f578d1..a7b580ff3 100644 --- a/ui/src/workflow/icons/variable-assign-node-icon.vue +++ b/ui/src/workflow/icons/variable-assign-node-icon.vue @@ -1,5 +1,5 @@ diff --git a/ui/src/workflow/nodes/base-node/component/UserInputFieldTable.vue b/ui/src/workflow/nodes/base-node/component/UserInputFieldTable.vue index f0eaa0daf..5ef1e1f2a 100644 --- a/ui/src/workflow/nodes/base-node/component/UserInputFieldTable.vue +++ b/ui/src/workflow/nodes/base-node/component/UserInputFieldTable.vue @@ -1,6 +1,6 @@ - + diff --git a/ui/src/workflow/nodes/variable-assign-node/index.vue b/ui/src/workflow/nodes/variable-assign-node/index.vue index ecd8fd31b..a88bccec9 100644 --- a/ui/src/workflow/nodes/variable-assign-node/index.vue +++ b/ui/src/workflow/nodes/variable-assign-node/index.vue @@ -7,6 +7,7 @@ require-asterisk-position="right" label-width="auto" ref="replyNodeFormRef" + hide-required-asterisk > @@ -212,6 +203,7 @@ function submitDialog(val: string) { const replyNodeFormRef = ref() const nodeCascaderRef = ref() const nodeCascaderRef2 = ref() + const validate = async () => { // console.log(replyNodeFormRef.value.validate()) let ps = [