1717import asyncio
1818from app .config .setting import settings
1919import json
20+ import base64
21+
22+ from app .utils .common_utils import get_current_files
2023
2124
2225def delete_color_control_char (string ):
@@ -284,12 +287,19 @@ async def execute_code(self, code: str) -> tuple[str, bool, str]:
284287 f"[{ item .format } 图片已生成,内容为 base64,未展示]"
285288 )
286289
290+ combined_text = "\n " .join (text_to_gpt )
291+
292+ # 在代码执行完成后,立即同步文件
293+ try :
294+ await self .download_all_files_from_sandbox ()
295+ logger .info ("文件同步完成" )
296+ except Exception as e :
297+ logger .error (f"文件同步失败: { str (e )} " )
298+
287299 # 保存到分段内容
288300 ## TODO: Base64 等图像需要优化
289301 await self ._push_to_websocket (content_to_display )
290302
291- combined_text = "\n " .join (text_to_gpt )
292-
293303 return (
294304 combined_text ,
295305 error_occurred ,
@@ -302,6 +312,7 @@ async def _push_to_websocket(self, content_to_display: list[OutputItem] | None):
302312 agent_msg = CoderMessage (
303313 agent_type = AgentType .CODER ,
304314 code_results = content_to_display ,
315+ files = get_current_files (self .work_dir , "all" ),
305316 )
306317 logger .debug (f"发送消息: { agent_msg .model_dump_json ()} " )
307318 await redis_manager .publish_message (
@@ -346,36 +357,71 @@ def get_code_output(self, section: str) -> str:
346357
347358 async def cleanup (self ):
348359 """清理资源并关闭沙箱"""
349-
350- if not await self .sbx .is_running ():
351- logger .warning ("沙箱已经关闭了" )
352-
353360 try :
354361 if self .sbx :
355- ## TODO: 生成一个文件,下载一份文件
356- await self .download_all_files_from_sandbox ()
357- await self .sbx .kill ()
358- logger .info ("成功关闭沙箱环境" )
362+ if await self .sbx .is_running ():
363+ try :
364+ await self .download_all_files_from_sandbox ()
365+ except Exception as e :
366+ logger .error (f"下载文件失败: { str (e )} " )
367+ finally :
368+ await self .sbx .kill ()
369+ logger .info ("成功关闭沙箱环境" )
370+ else :
371+ logger .warning ("沙箱已经关闭,跳过清理步骤" )
359372 except Exception as e :
360373 logger .error (f"清理沙箱环境失败: { str (e )} " )
361- raise
374+ # 这里可以选择不抛出异常,因为这是清理步骤
362375
363376 async def download_all_files_from_sandbox (self ) -> None :
364- """从沙箱中下载所有文件 """
377+ """从沙箱中下载所有文件并与本地同步 """
365378 try :
366- files = await self .sbx .files .list ("/home/user" )
367- for file in files :
368- content = await self .sbx .files .read (file .path )
369- output_path = os .path .join (self .work_dir , file .name )
370- # 修复:确保写入文件时 content 一定是 bytes 类型
371- if isinstance (content , str ):
372- content = content .encode ("utf-8" )
373- with open (output_path , "wb" ) as f :
374- f .write (content )
375- logger .info (f"成功下载文件: { file .name } " )
379+ # 获取沙箱中的文件列表
380+ sandbox_files = await self .sbx .files .list ("/home/user" )
381+ sandbox_files_dict = {f .name : f for f in sandbox_files }
382+
383+ # 获取本地文件列表
384+ local_files = set ()
385+ if os .path .exists (self .work_dir ):
386+ local_files = set (os .listdir (self .work_dir ))
387+
388+ # 下载新文件或更新已修改的文件
389+ for file in sandbox_files :
390+ try :
391+ local_path = os .path .join (self .work_dir , file .name )
392+ should_download = True
393+
394+ # 检查文件是否需要更新
395+ if file .name in local_files :
396+ # 这里可以添加文件修改时间或内容哈希的比较
397+ # 暂时简单处理,有同名文件就更新
398+ pass
399+
400+ if should_download :
401+ content = await self .sbx .files .read (file .path )
402+
403+ # 确保目标目录存在
404+ os .makedirs (self .work_dir , exist_ok = True )
405+
406+ # 写入文件
407+ with open (local_path , "wb" ) as f :
408+ if isinstance (content , str ):
409+ if "," in content : # 处理data URL格式
410+ content = content .split ("," )[1 ]
411+ content = base64 .b64decode (content )
412+ else :
413+ content = content .encode ("utf-8" )
414+ f .write (content )
415+ logger .info (f"同步文件: { file .name } " )
416+
417+ except Exception as e :
418+ logger .error (f"同步文件 { file .name } 失败: { str (e )} " )
419+ continue
420+
421+ logger .info ("文件同步完成" )
422+
376423 except Exception as e :
377- logger .error (f"下载文件失败: { str (e )} " )
378- # 这里不再 raise,防止 cleanup 阶段因沙箱已关闭而报错
424+ logger .error (f"文件同步失败: { str (e )} " )
379425
380426 async def shutdown_sandbox (self ):
381427 """关闭沙箱环境"""
0 commit comments