Skip to content

Commit c93c8cb

Browse files
Merge remote-tracking branch 'upstream/v2' into perf
2 parents 12b0b93 + c0d86ad commit c93c8cb

File tree

12 files changed

+138
-36
lines changed

12 files changed

+138
-36
lines changed

apps/application/flow/step_node/variable_assign_node/impl/base_variable_assign_node.py

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,33 +60,44 @@ def handle(self, variable, evaluation):
6060
val = variable['value']
6161
evaluation(variable, val)
6262
result['output_value'] = val
63-
else:
63+
elif variable['source'] == 'referencing':
6464
reference = self.get_reference_content(variable['reference'])
6565
evaluation(variable, reference)
6666
result['output_value'] = reference
67+
else:
68+
val = None
69+
evaluation(variable, val)
70+
result['output_value'] = val
71+
72+
# 获取输入输出值的类型,用于显示在执行详情页面中
73+
result['input_type'] = type(result.get('input_value')).__name__ if result.get('input_value') is not None else 'null'
74+
result['output_type'] = type(result.get('output_value')).__name__ if result.get('output_value') is not None else 'null'
75+
6776
return result
6877

6978
def execute(self, variable_list, **kwargs) -> NodeResult:
70-
#
7179
result_list = []
72-
is_chat = False
80+
contains_chat_variable = False
7381
for variable in variable_list:
74-
if 'fields' not in variable:
82+
if not variable.get('fields'):
7583
continue
76-
if 'global' == variable['fields'][0]:
84+
85+
field0 = variable['fields'][0]
86+
if 'global' == field0:
7787
result = self.handle(variable, self.global_evaluation)
7888
result_list.append(result)
79-
if 'chat' == variable['fields'][0]:
89+
elif 'chat' == field0:
8090
result = self.handle(variable, self.chat_evaluation)
8191
result_list.append(result)
82-
is_chat = True
83-
if 'loop' == variable['fields'][0]:
92+
contains_chat_variable = True
93+
elif 'loop' == field0:
8494
result = self.handle(variable, self.loop_evaluation)
8595
result_list.append(result)
86-
if 'output' == variable['fields'][0]:
96+
elif 'output' == field0:
8797
result = self.handle(variable, self.out_evaluation)
8898
result_list.append(result)
89-
if is_chat:
99+
100+
if contains_chat_variable:
90101
from application.flow.loop_workflow_manage import LoopWorkflowManage
91102
if isinstance(self.workflow_manage, LoopWorkflowManage):
92103
self.workflow_manage.parentWorkflowManage.get_chat_info().set_chat_variable(

apps/tools/serializers/tool.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,6 +1356,27 @@ def upload(self):
13561356
file.save(self.data.get('file').read())
13571357
return file_id
13581358

1359+
class DownloadSkillFile(serializers.Serializer):
1360+
user_id = serializers.UUIDField(required=True, label=_("User ID"))
1361+
workspace_id = serializers.CharField(required=True, label=_("workspace id"))
1362+
tool_id = serializers.CharField(required=True, label=_("tool id"))
1363+
1364+
def download(self):
1365+
self.is_valid(raise_exception=True)
1366+
tool = QuerySet(Tool).filter(
1367+
id=self.data.get('tool_id'), workspace_id=self.data.get('workspace_id'), tool_type=ToolType.SKILL
1368+
).first()
1369+
1370+
if tool is None:
1371+
raise AppApiException(500, _('Tool does not exist'))
1372+
skill_file = QuerySet(File).filter(id=tool.code).first()
1373+
if skill_file is None:
1374+
raise AppApiException(500, _('Skill file does not exist'))
1375+
1376+
response = HttpResponse(content_type='application/zip', content=skill_file.get_bytes())
1377+
response['Content-Disposition'] = f'attachment; filename="{skill_file.file_name}"'
1378+
return response
1379+
13591380
class GenerateCodeSerializer(serializers.Serializer):
13601381
workspace_id = serializers.CharField(required=True, label=_('Workspace ID'))
13611382
model_id = serializers.UUIDField(required=True, label=_('Model ID'))

apps/tools/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
path('workspace/<str:workspace_id>/tool/<str:tool_id>/add_internal_tool', views.ToolView.AddInternalTool.as_view()),
2929
path('workspace/<str:workspace_id>/tool/<str:tool_id>/add_store_tool', views.ToolView.AddStoreTool.as_view()),
3030
path('workspace/<str:workspace_id>/tool/<str:tool_id>/update_store_tool', views.ToolView.UpdateStoreTool.as_view()),
31+
path('workspace/<str:workspace_id>/tool/<str:tool_id>/download_skill_file', views.ToolView.DownloadSkillFile.as_view()),
3132
path('workspace/<str:workspace_id>/tool/<str:tool_id>/tool_record/<str:record_id>', views.ToolView.ToolRecord.as_view()),
3233
path('workspace/<str:workspace_id>/tool/<str:tool_id>/tool_record/<int:current_page>/<int:page_size>', views.ToolView.PageToolRecord.as_view()),
3334
path('workspace/<str:workspace_id>/tool/<int:current_page>/<int:page_size>', views.ToolView.Page.as_view()),

apps/tools/views/tool.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
from rest_framework.request import Request
66
from rest_framework.views import APIView
77

8+
from common import result
89
from common.auth import TokenAuth
910
from common.auth.authentication import has_permissions, check_batch_permissions
1011
from common.constants.permission_constants import PermissionConstants, RoleConstants, ViewPermission, CompareConstants
1112
from common.log.log import log
12-
from common import result
1313
from tools.api.tool import ToolCreateAPI, ToolEditAPI, ToolReadAPI, ToolDeleteAPI, ToolTreeReadAPI, ToolDebugApi, \
1414
ToolExportAPI, ToolImportAPI, ToolPageAPI, PylintAPI, EditIconAPI, GetInternalToolAPI, AddInternalToolAPI, \
1515
ToolBatchOperateAPI
@@ -25,6 +25,7 @@ def get_tool_operation_object(tool_id):
2525
}
2626
return {}
2727

28+
2829
def get_tool_operation_object_batch(tool_id_list):
2930
tool_model_list = QuerySet(model=Tool).filter(id__in=tool_id_list)
3031
if tool_model_list is not None:
@@ -684,6 +685,22 @@ def put(self, request: Request, workspace_id: str):
684685
'file': request.FILES.get('file'),
685686
}).upload())
686687

688+
class DownloadSkillFile(APIView):
689+
authentication_classes = [TokenAuth]
690+
691+
@has_permissions(
692+
PermissionConstants.TOOL_EDIT.get_workspace_permission(),
693+
PermissionConstants.TOOL_EDIT.get_workspace_permission_workspace_manage_role(),
694+
RoleConstants.WORKSPACE_MANAGE.get_workspace_role(),
695+
RoleConstants.USER.get_workspace_role()
696+
)
697+
def get(self, request: Request, workspace_id: str, tool_id: str):
698+
return ToolSerializer.DownloadSkillFile(data={
699+
'workspace_id': workspace_id,
700+
'user_id': request.user.id,
701+
'tool_id': tool_id,
702+
}).download()
703+
687704
class GenerateCode(APIView):
688705
authentication_classes = [TokenAuth]
689706

pyproject.toml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ dependencies = [
1111
"django-redis==6.0.0",
1212
"django-db-connection-pool==1.2.6",
1313
"django-mptt==0.17.0",
14+
"djangorestframework==3.17.1",
1415
"psycopg[binary]==3.2.9",
1516
"python-dotenv==1.1.1",
1617
"uuid-utils==0.14.0",
@@ -21,7 +22,8 @@ dependencies = [
2122
"beautifulsoup4==4.13.4",
2223
"jieba==0.42.1",
2324
"langchain==1.2.15",
24-
"langchain-openai==1.1.12",
25+
"langchain-core==1.2.29",
26+
"langchain-openai==1.1.13",
2527
"langchain-anthropic==1.4.0",
2628
"langchain-community==0.4.1",
2729
"langchain-deepseek==1.0.1",
@@ -31,7 +33,7 @@ dependencies = [
3133
"langchain-ollama==1.1.0",
3234
"langchain-aws==1.4.3",
3335
"langgraph==1.1.6",
34-
"deepagents==0.4.12",
36+
"deepagents==0.5.2",
3537
"torch==2.8.0",
3638
"numpy==1.26.4",
3739
"sentence-transformers==5.0.0",
@@ -42,7 +44,7 @@ dependencies = [
4244
"tencentcloud-sdk-python==3.0.1420",
4345
"xinference-client==1.7.1.post1",
4446
"anthropic==0.89.0",
45-
"dashscope==1.25.7",
47+
"dashscope==1.25.16",
4648
"celery[sqlalchemy]==5.5.3",
4749
"django-celery-beat==2.8.1",
4850
"celery-once==3.0.1",
@@ -53,15 +55,15 @@ dependencies = [
5355
"xlrd==2.0.2",
5456
"xlwt==1.3.0",
5557
"pymupdf==1.26.3",
56-
"pypdf==6.10.0",
58+
"pypdf==6.10.1",
5759
"pydub==0.25.1",
5860
"pysilk==0.0.1",
5961
"gunicorn==23.0.0",
6062
"python-daemon==3.1.2",
6163
"websockets==15.0.1",
6264
"pylint==3.3.7",
6365
"cohere==5.17.0",
64-
"jsonpath-ng==1.8.0",
66+
"jsonpath-ng==1.8.0"
6567
]
6668

6769
[tool.uv]

ui/src/api/system-resource-management/tool.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Result } from '@/request/Result'
2-
import { get, post, del, put, exportFile, postStream } from '@/request/index'
2+
import { get, post, del, put, exportFile, postStream, download } from '@/request/index'
33
import { type Ref } from 'vue'
44
import type { pageRequest } from '@/api/type/common'
55
import type { toolData } from '@/api/type/tool'
@@ -146,6 +146,13 @@ const uploadSkillFile: (data: toolData, loading?: Ref<boolean>) => Promise<Resul
146146
return put(`${prefix}/upload_skill_file`, data, undefined, loading)
147147
}
148148

149+
const downloadSkillFile: (tool_id: string, loading?: Ref<boolean>) => Promise<Result<any>> = (
150+
tool_id,
151+
loading,
152+
) => {
153+
return download(`${prefix}/${tool_id}/download_skill_file`, 'GET', undefined, undefined, loading)
154+
}
155+
149156
const generateCode: (data: any) => Promise<Result<any>> = (data: any) => {
150157
const p = (window.MaxKB?.prefix ? window.MaxKB?.prefix : '/admin') + '/api'
151158
return postStream(`${p}${prefix}/generate_code`, data)
@@ -227,6 +234,7 @@ export default {
227234
pageToolRecord,
228235
getToolRecordDetail,
229236
uploadSkillFile,
237+
downloadSkillFile,
230238
generateCode,
231239
listToolWorkflowVersion,
232240
updateToolWorkflowVersion,

ui/src/api/system-shared/tool.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import {Result} from '@/request/Result'
2-
import {get, post, del, put, exportFile, postStream} from '@/request/index'
2+
import { get, post, del, put, exportFile, postStream, download } from '@/request/index'
33
import {type Ref} from 'vue'
44
import type {pageRequest} from '@/api/type/common'
55
import type {toolData, AddInternalToolParam} from '@/api/type/tool'
@@ -200,6 +200,13 @@ const uploadSkillFile: (data: toolData, loading?: Ref<boolean>) => Promise<Resul
200200
return put(`${prefix}/upload_skill_file`, data, undefined, loading)
201201
}
202202

203+
const downloadSkillFile: (tool_id: string, loading?: Ref<boolean>) => Promise<Result<any>> = (
204+
tool_id,
205+
loading,
206+
) => {
207+
return download(`${prefix}/${tool_id}/download_skill_file`, 'GET', undefined, undefined, loading)
208+
}
209+
203210
const generateCode: (data: any) => Promise<Result<any>> = (
204211
data: any,
205212
) => {
@@ -301,6 +308,7 @@ export default {
301308
pageToolRecord,
302309
getToolRecordDetail,
303310
uploadSkillFile,
311+
downloadSkillFile,
304312
generateCode,
305313
putToolWorkflow,
306314
importToolWorkflow,

ui/src/api/tool/tool.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Result } from '@/request/Result'
2-
import { get, post, del, put, exportFile, postStream } from '@/request/index'
2+
import { get, post, del, put, exportFile, postStream, download } from '@/request/index'
33
import { type Ref } from 'vue'
44
import type { pageRequest } from '@/api/type/common'
55
import type { AddInternalToolParam, toolData } from '@/api/type/tool'
@@ -195,6 +195,14 @@ const uploadSkillFile: (data: toolData, loading?: Ref<boolean>) => Promise<Resul
195195
) => {
196196
return put(`${prefix.value}/upload_skill_file`, data, undefined, loading)
197197
}
198+
199+
const downloadSkillFile: (tool_id: string, loading?: Ref<boolean>) => Promise<Result<any>> = (
200+
tool_id,
201+
loading,
202+
) => {
203+
return download(`${prefix.value}/${tool_id}/download_skill_file`, 'GET', undefined, undefined, loading)
204+
}
205+
198206
/**
199207
* 保存工具工作流
200208
* @param tool_id
@@ -348,6 +356,7 @@ export default {
348356
pageToolRecord,
349357
getToolRecordDetail,
350358
uploadSkillFile,
359+
downloadSkillFile,
351360
putToolWorkflow,
352361
importToolWorkflow,
353362
listToolWorkflowVersion,

ui/src/components/execution-detail-card/index.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@
882882
</h5>
883883
<div class="p-8-12 border-t-dashed lighter">
884884
<div v-for="(f, i) in data.result_list" :key="i" class="mb-8">
885-
<span class="color-secondary">{{ f.name }}:</span> {{ f.input_value }}
885+
<span class="color-secondary">{{ f.name }} ({{ f.input_type }}):</span> {{ f.input_value }}
886886
</div>
887887
</div>
888888
</div>
@@ -892,7 +892,7 @@
892892
</h5>
893893
<div class="p-8-12 border-t-dashed lighter">
894894
<div v-for="(f, i) in data.result_list" :key="i" class="mb-8">
895-
<span class="color-secondary">{{ f.name }}:</span> {{ f.output_value }}
895+
<span class="color-secondary">{{ f.name }} ({{ f.output_type }}):</span> {{ f.output_value }}
896896
</div>
897897
</div>
898898
</div>

ui/src/views/paragraph/index.vue

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -444,15 +444,18 @@ function openGenerateDialog(row?: any) {
444444
}
445445
446446
function onEnd(event?: any, params?: any, index?: number) {
447-
// console.log('onEnd', event, params, index)
447+
console.log('onEnd', event, params, index)
448+
if (event && event.newIndex === event.oldIndex) {
449+
// 没有移动
450+
return
451+
}
448452
const p = cloneDeep(params)
449453
if (p) {
450454
p.new_position = p.new_position + 1 // 由于拖拽时会将当前段落位置作为新位置,所以需要加1
451455
}
452456
const obj = p ?? {
453457
paragraph_id: paragraphDetail.value[event.newIndex].id, // 当前拖动的段落ID
454-
new_position:
455-
paragraphDetail.value[event.newIndex + 1]?.position || paragraphDetail.value.length, // 新位置的段落位置
458+
new_position: event.newIndex + 1,
456459
}
457460
// console.log(paragraphDetail.value[event.newIndex], obj)
458461
loadSharedApi({ type: 'paragraph', systemType: apiType.value }).putAdjustPosition(

0 commit comments

Comments
 (0)