Skip to content

Commit 104696e

Browse files
committed
fix: update file handling functions
1 parent bd43d2f commit 104696e

File tree

2 files changed

+62
-28
lines changed

2 files changed

+62
-28
lines changed

apps/application/flow/step_node/tool_lib_node/impl/base_tool_lib_node.py

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
@date:2024/8/8 17:49
77
@desc:
88
"""
9-
import base64
9+
10+
import ast
1011
import io
1112
import json
1213
import mimetypes
@@ -195,31 +196,23 @@ def execute(self, tool_lib_id, input_field_list, **kwargs) -> NodeResult:
195196
else:
196197
all_params = init_params_default_value | params
197198
if self.node.properties.get('kind') == 'data-source':
198-
download_file_list = []
199-
download_list = function_executor.exec_code(
200-
tool_lib.code,
201-
{**all_params, **self.workflow_params.get('data_source')},
202-
function_name='get_down_file_list'
203-
)
204-
for item in download_list:
205-
result = function_executor.exec_code(
206-
tool_lib.code,
207-
{**all_params, **self.workflow_params.get('data_source'),
208-
'download_item': item},
209-
function_name='download'
210-
)
211-
file_bytes = result.get('file_bytes', [])
212-
chunks = []
213-
for chunk in file_bytes:
214-
chunks.append(base64.b64decode(chunk))
215-
file = bytes_to_uploaded_file(b''.join(chunks), result.get('name'))
216-
file_url = self.upload_knowledge_file(file)
217-
download_file_list.append({'file_id': file_url.split('/')[-1], 'name': result.get('name')})
218-
all_params = {
219-
**all_params, **self.workflow_params.get('data_source'),
220-
'download_file_list': download_file_list
221-
}
222-
result = download_file_list
199+
exist = function_executor.exist_function(tool_lib.code, 'get_download_file_list')
200+
if exist:
201+
download_file_list = []
202+
download_list = function_executor.exec_code(tool_lib.code,
203+
{**all_params, **self.workflow_params.get('data_source')},
204+
function_name='get_download_file_list')
205+
for item in download_list:
206+
result = function_executor.exec_code(tool_lib.code,
207+
{**all_params, **self.workflow_params.get('data_source'),
208+
'download_item': item},
209+
function_name='download')
210+
file = bytes_to_uploaded_file(ast.literal_eval(result.get('file_bytes')), result.get('name'))
211+
file_url = self.upload_knowledge_file(file)
212+
download_file_list.append({'file_id': file_url, 'name': result.get('name')})
213+
result = download_file_list
214+
else:
215+
result = function_executor.exec_code(tool_lib.code, all_params)
223216
else:
224217
result = function_executor.exec_code(tool_lib.code, all_params)
225218
return NodeResult({'result': result},
@@ -237,7 +230,7 @@ def upload_knowledge_file(self, file):
237230
'meta': meta,
238231
'source_id': knowledge_id,
239232
'source_type': FileSourceType.KNOWLEDGE.value
240-
}).upload()
233+
}).upload().replace("./oss/file/", '')
241234
file.close()
242235
return file_url
243236

apps/common/utils/tool_code.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,47 @@ def init_sandbox_dir():
7474
except Exception as e:
7575
maxkb_logger.error(f'Exception: {e}', exc_info=True)
7676

77+
def exist_function(self, code_str, name):
78+
_id = str(uuid.uuid7())
79+
python_paths = CONFIG.get_sandbox_python_package_paths().split(',')
80+
set_run_user = f'os.setgid({pwd.getpwnam(_run_user).pw_gid});os.setuid({pwd.getpwnam(_run_user).pw_uid});' if _enable_sandbox else ''
81+
_exec_code = f"""
82+
try:
83+
import os, sys, json
84+
path_to_exclude = ['/opt/py3/lib/python3.11/site-packages', '/opt/maxkb-app/apps']
85+
sys.path = [p for p in sys.path if p not in path_to_exclude]
86+
sys.path += {python_paths}
87+
locals_v={{}}
88+
globals_v={{}}
89+
{set_run_user}
90+
os.environ.clear()
91+
exec({dedent(code_str)!a}, globals_v, locals_v)
92+
exec_result=locals_v.__contains__('{name}')
93+
sys.stdout.write("\\n{_id}:")
94+
json.dump({{'code':200,'msg':'success','data':exec_result}}, sys.stdout, default=str)
95+
except Exception as e:
96+
if isinstance(e, MemoryError): e = Exception("Cannot allocate more memory: exceeded the limit of {_process_limit_mem_mb} MB.")
97+
sys.stdout.write("\\n{_id}:")
98+
json.dump({{'code':500,'msg':str(e),'data':False}}, sys.stdout, default=str)
99+
sys.stdout.flush()
100+
"""
101+
maxkb_logger.debug(f"Sandbox execute code: {_exec_code}")
102+
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=True) as f:
103+
f.write(_exec_code)
104+
f.flush()
105+
subprocess_result = self._exec(f.name)
106+
if subprocess_result.returncode != 0:
107+
raise Exception(subprocess_result.stderr or subprocess_result.stdout or "Unknown exception occurred")
108+
lines = subprocess_result.stdout.splitlines()
109+
result_line = [line for line in lines if line.startswith(_id)]
110+
if not result_line:
111+
maxkb_logger.error("\n".join(lines))
112+
raise Exception("No result found.")
113+
result = json.loads(result_line[-1].split(":", 1)[1])
114+
if result.get('code') == 200:
115+
return result.get('data')
116+
raise Exception(result.get('msg'))
117+
77118
def exec_code(self, code_str, keywords, function_name=None):
78119
_id = str(uuid.uuid7())
79120
action_function = f'({function_name !a}, locals_v.get({function_name !a}))' if function_name else 'locals_v.popitem()'
@@ -213,7 +254,7 @@ def get_tool_mcp_config(self, code, params):
213254
],
214255
'cwd': _sandbox_path,
215256
'env': {
216-
'LD_PRELOAD': f'{_sandbox_path}/lib/sandbox.so',
257+
'LD_PRELOAD': f'{_sandbox_path}/lib/sandbox.so',
217258
},
218259
'transport': 'stdio',
219260
}

0 commit comments

Comments
 (0)