fix(sandbox): 主智能体编排期沙盒 idle 超时被误杀,加主动 keepalive 续命 - #1005
Conversation
|
Codex Review: 补充核查(修正此前预 review):当前主路径已经启用 在本 PR head 两种机制解决不同问题:按需重建可以重新提供环境,并重新挂载持久 Workdir/UserWorkspace;主动 keepalive 则能避免原容器的 /tmp、运行中进程及未持久化环境状态因 idle 回收而丢失。只有当前任务确实依赖这些状态跨编排等待存续时,才有独立的续命需求。根 Agent 和子 Agent 共享 runtime scope,不能仅根据“主 Agent 没有执行命令”认定整个 sandbox 无活动。 建议先不按目前的 bug-fix 理由合并:若验收只要求回收后仍能执行命令并读取持久产物,优先验证现有按需重建即可;若要求同一执行树内临时 runtime 状态连续存续,请明确该契约,再证明主动续命与 Run 生命周期绑定。当前实现遍历所有缓存连接,缓存存在本身不等于 Run 仍在执行。 此前建议“恢复惰性 touch 后应因 sandbox 不可用失败”不够准确,应更正为:先建立实际缺陷的独立复现;若缺陷是临时状态丢失,负向测试应验证该状态丢失,而不是假定不能重建。合并前按最终目标补充真实 worker/provisioner 验证及 tracked decision。 已有验证:在该 PR head 独立源码快照运行 |
|
你说得对,本 PR 的根因不成立。撤回。 核实结论你的判断完全正确,我逐条验证后确认:
关于 keepalive 本身你在 [P1] 里指出的另一点也成立,而且我的实现确实有这个缺陷:「缓存里存在连接」不等于「Run 仍在执行」。现有实现遍历所有缓存连接续命,会让已经结束但尚未 你提出的两种机制的区别我认同:按需重建解决的是「回收后仍能执行命令并读取持久产物」,主动 keepalive 只对「同一执行树内临时 runtime 状态( 处置关闭本 PR。分支保留( 如果后续确有「临时 runtime 状态需跨编排等待存续」的需求,我会按你的建议重做:先给出可复现证据,再把续命绑定到 Run 生命周期(只对仍在执行、且声明该契约的 Run 续命),并补 tracked decision——而不是像现在这样遍历全部缓存连接。 感谢你两次纠正,这次的核查让我把「注释当事实」这个错误暴露出来了。 |
现象
编排型主智能体(如 deep-research)在调度子智能体期间,可能几分钟不执行任何沙盒命令。此时沙盒被 provisioner 按 idle 超时清理,之后主智能体再想用沙盒时
create_if_missing=False无法重建,任务报sandbox is unavailable直接失败。机理
原实现是「惰性 touch」——只在真正要执行命令前才
touch续命。但主智能体编排期根本不碰沙盒,惰性 touch 永远不触发,沙盒就「安静地」到了 idle 超时被回收。改进方法
在
ProvisionerSandboxProvider里加一个后台 daemon 线程,按SANDBOX_KEEPALIVE_INTERVAL_SECONDS(默认 30s)周期遍历所有活跃沙盒连接,对到期的执行touch续命;touch 发现沙盒已被清理则移除连接;shutdown()时stop_event优雅停线程。效果
主智能体即使长时间不执行命令,沙盒也不会被误回收;编排结束后沙盒仍可用,任务不再因
sandbox is unavailable中断。验证
新增 4 个单测:keepalive touch 报活并更新时间戳、tick 移除已清理沙盒、tick 保留存活沙盒、tick 跳过未到期沙盒。