feat:增强需求澄清与任务管理功能
更新了 .env.example,新增聊天模型配置,以提升对话处理能力。 增强了 README.md,反映了包括需求澄清、代码复用和自动重试在内的新功能。 重构了 agent.py,以支持多模型交互,并为无法在本地执行的任务新增了引导处理逻辑。 改进了 SandboxRunner,增加了任务执行成功校验,并加入了工作区清理功能。 扩展了 HistoryManager,支持任务摘要生成以及记录的批量删除。 优化了 chat_view.py 和 history_view.py 中的 UI 组件,提升用户体验,包括 Markdown 渲染和任务管理选项。
This commit is contained in:
@@ -119,8 +119,15 @@ class SandboxRunner:
|
||||
duration_ms=duration_ms
|
||||
)
|
||||
|
||||
# 判断是否成功:return code 为 0 且没有明显的失败迹象
|
||||
success = self._check_execution_success(
|
||||
result.returncode,
|
||||
result.stdout,
|
||||
result.stderr
|
||||
)
|
||||
|
||||
return ExecutionResult(
|
||||
success=result.returncode == 0,
|
||||
success=success,
|
||||
task_id=task_id,
|
||||
stdout=result.stdout,
|
||||
stderr=result.stderr,
|
||||
@@ -187,6 +194,99 @@ class SandboxRunner:
|
||||
short_uuid = uuid.uuid4().hex[:6]
|
||||
return f"{timestamp}_{short_uuid}"
|
||||
|
||||
def clear_workspace(self, clear_input: bool = True, clear_output: bool = True) -> None:
|
||||
"""
|
||||
清空工作目录
|
||||
|
||||
Args:
|
||||
clear_input: 是否清空 input 目录
|
||||
clear_output: 是否清空 output 目录
|
||||
"""
|
||||
if clear_input:
|
||||
self._clear_directory(self.input_dir)
|
||||
if clear_output:
|
||||
self._clear_directory(self.output_dir)
|
||||
|
||||
def _clear_directory(self, directory: Path) -> None:
|
||||
"""
|
||||
清空目录中的所有文件和子目录
|
||||
|
||||
Args:
|
||||
directory: 要清空的目录路径
|
||||
"""
|
||||
if not directory.exists():
|
||||
return
|
||||
|
||||
import shutil
|
||||
|
||||
for item in directory.iterdir():
|
||||
try:
|
||||
if item.is_file():
|
||||
item.unlink()
|
||||
elif item.is_dir():
|
||||
shutil.rmtree(item)
|
||||
except Exception as e:
|
||||
# 忽略删除失败的文件(可能被占用)
|
||||
print(f"Warning: Failed to delete {item}: {e}")
|
||||
|
||||
def _check_execution_success(self, return_code: int, stdout: str, stderr: str) -> bool:
|
||||
"""
|
||||
检查执行是否成功
|
||||
|
||||
判断逻辑:
|
||||
1. return code 必须为 0
|
||||
2. 检查输出中是否有失败迹象
|
||||
3. 如果有成功和失败的统计,根据失败数量判断
|
||||
"""
|
||||
# return code 不为 0 直接判定失败
|
||||
if return_code != 0:
|
||||
return False
|
||||
|
||||
# 检查 stderr 是否有内容(通常表示有错误)
|
||||
if stderr and stderr.strip():
|
||||
# 如果 stderr 有实质内容,可能是失败
|
||||
# 但有些程序会把警告也输出到 stderr,所以不直接判定失败
|
||||
pass
|
||||
|
||||
# 检查 stdout 中的失败迹象
|
||||
output = stdout.lower() if stdout else ""
|
||||
|
||||
# 查找失败统计模式,如 "失败 27 个" 或 "failed: 27"
|
||||
import re
|
||||
|
||||
# 中文模式:成功 X 个, 失败 Y 个
|
||||
pattern_cn = r'成功\s*(\d+)\s*个.*失败\s*(\d+)\s*个'
|
||||
match = re.search(pattern_cn, stdout if stdout else "")
|
||||
if match:
|
||||
success_count = int(match.group(1))
|
||||
fail_count = int(match.group(2))
|
||||
# 如果有失败的,判定为失败
|
||||
if fail_count > 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
# 英文模式:success: X, failed: Y
|
||||
pattern_en = r'success[:\s]+(\d+).*fail(?:ed)?[:\s]+(\d+)'
|
||||
match = re.search(pattern_en, output)
|
||||
if match:
|
||||
success_count = int(match.group(1))
|
||||
fail_count = int(match.group(2))
|
||||
if fail_count > 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
# 检查是否有明显的失败关键词
|
||||
failure_keywords = ['失败', 'error', 'exception', 'traceback', 'failed']
|
||||
for keyword in failure_keywords:
|
||||
if keyword in output:
|
||||
# 如果包含失败关键词,进一步检查是否是统计信息
|
||||
# 如果是 "失败 0 个" 这种,不算失败
|
||||
if '失败 0' in stdout or '失败: 0' in stdout or 'failed: 0' in output or 'failed 0' in output:
|
||||
continue
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def _get_safe_env(self) -> dict:
|
||||
"""获取安全的环境变量(移除网络代理等)"""
|
||||
safe_env = os.environ.copy()
|
||||
|
||||
Reference in New Issue
Block a user