From dfac0acfa6d2b6eb8b0b8fa8e9f523a57a55e7da Mon Sep 17 00:00:00 2001 From: caoqianming Date: Tue, 26 May 2026 16:13:16 +0800 Subject: [PATCH] =?UTF-8?q?Stage=20C=20Step=203:=20DockerExecutor=20?= =?UTF-8?q?=E9=9B=86=E6=88=90=20AgentLoop=20+=20web=20lifespan=20reaper?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - core/executor_docker.py 新增 DockerExecutor:组合 HostExecutor+SandboxPool, shell/run_python 走 docker exec(setsid + --user 1000:1000 + --workdir), 其他工具直通 host(§7.5 #6 信任域二分) - run_python tmp .py 落 /.zcbot_tmp//(dotfile,/v1/files 天然过滤),容器内对应 /workspace/.zcbot_tmp/...,跑完 unlink - ZCBOT_SANDBOX_BACKEND=host|docker env 切 backend,默 host(Windows dogfood 零变化);docker 路径 pool 未 init → fail-fast 不静默退化 - web/app.py lifespan:docker backend 启动时 init_pool + shutdown_all 清孤儿 + 60s 后台 reaper(run_in_executor 调 sync reap_idle);关闭时 cancel + 兜底清 - pool.py 顺手清 Step 2 债:asyncio.Lock → threading.Lock,ensure 改同步 (主使用方是 BG 线程 tool call,ephemeral loop 会让 asyncio.Lock 跨锁失效) - Cancel limitation 接受:Popen.kill() 仅杀 docker CLI 客户端,容器内进程靠 idle 5min reaper 兜底;升级到 PGID 协议(§7.5 #3)等用户反馈触发 - tests/test_executor_docker.py 11 测试覆盖关键路径(host 直通/argv 形态/ tmp 清理/timeout/cancel/未知工具/enable_run_python=False) - DESIGN.md 不动(纯按 §7.5 #5 #6 既有协议实施) - RUN.md 加 ZCBOT_SANDBOX_BACKEND env 段 + 切 docker 的前置条件 + 集成验证路径 - unittest discover 12/12 PASS Co-Authored-By: Claude Opus 4.7 (1M context) --- PROGRESS.md | 5 +- RUN.md | 35 ++++- core/agent_builder.py | 42 ++++- core/executor_docker.py | 239 ++++++++++++++++++++++++++++ core/sandbox/__init__.py | 35 ++++- core/sandbox/pool.py | 33 ++-- tests/test_executor_docker.py | 285 ++++++++++++++++++++++++++++++++++ web/app.py | 56 ++++++- 8 files changed, 703 insertions(+), 27 deletions(-) create mode 100644 core/executor_docker.py create mode 100644 tests/test_executor_docker.py diff --git a/PROGRESS.md b/PROGRESS.md index 98394bd..aaa6128 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -2,7 +2,7 @@ > 配合 `DESIGN.md`。本文件只记 phase 状态、决策偏差、文件量、下一步。每条 1-2 句:做了啥 + 关键判断;细节查 `git log` / `git diff` / `DESIGN §7.9`。 -最后更新:2026-05-26(Stage C Step 2:Docker per-user 容器池 + Dockerfile / init.sh / network ensure,代码就绪未集成 AgentLoop) +最后更新:2026-05-26(Stage C Step 3:DockerExecutor 集成 AgentLoop + web lifespan reaper,ZCBOT_SANDBOX_BACKEND env 切换 host/docker) --- @@ -15,7 +15,7 @@ | 5 | Eval Suite | ⏸ 不做 | dogfooding 替代,probe 覆盖健康检查 | | 6 | 长任务工程化 | 🟡 | task + 恢复 ✅;双层记忆 ✅;context 压缩未做 | | 7 | 打磨 | ❌ | Docker 沙盒 / 更多 skill | -| §7 SaaS | DESIGN §7 路线 | 🟡 | A 事件流化 ✅;B 完工 ✅;D `/v1` JSON API ✅;D' 过渡 auth + dev SPA ✅;单活 run 锁 + cancel ✅;0004 schema 瘦身 ✅;入口归位 ✅;真 OIDC 待;**C(Executor+docker sandbox)待 —— 外部用户开放 hard prereq,完成前仅 dogfood + 信任同事白名单;DoD 详 DESIGN §7.5 落地清单 6 条**。 | +| §7 SaaS | DESIGN §7 路线 | 🟡 | A 事件流化 ✅;B 完工 ✅;D `/v1` JSON API ✅;D' 过渡 auth + dev SPA ✅;单活 run 锁 + cancel ✅;0004 schema 瘦身 ✅;入口归位 ✅;真 OIDC 待;**C Step 1-3 ✅(Executor 接口 + Docker 池 + DockerExecutor 集成 AgentLoop,`ZCBOT_SANDBOX_BACKEND=docker` 切容器)**;Step 4 egress proxy + Step 3b PGID kill 协议待;**外部用户开放仍需 egress proxy + xfs project quota(§7.5 落地清单 #2 #4)**。 | --- @@ -23,6 +23,7 @@ ### 2026-05-26 +- **Stage C Step 3:DockerExecutor 集成 AgentLoop + web lifespan(`ZCBOT_SANDBOX_BACKEND=host|docker` env 切 backend)**:`core/executor_docker.py` `DockerExecutor` 组合 `HostExecutor` + `SandboxPool`,`call_tool` 按 §7.5 #6 信任域 dispatch:`shell` / `run_python` → `pool.ensure(user_id)` 拿容器名 + `docker exec --user 1000:1000 --workdir /workspace/ -e PYTHONIOENCODING=utf-8 setsid bash -c ` / `python