fix(web): bound unattended implementation turns
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled

This commit is contained in:
mes123456
2026-09-06 05:30:25 +08:00
parent 7257c04a49
commit 187deb0986
2 changed files with 22 additions and 0 deletions

View File

@@ -199,6 +199,8 @@ Rules:
- Preserve all existing dirty changes. Do not revert or rewrite unrelated work.
- Read only the owned paths and their direct imported types/helpers.
- For scoped searches, pass each owned path explicitly through the batch search runtime option; never pass a bare --runtime flag.
- Hard budget: at most 16 tool commands, including at most 8 read/search commands. After the read budget, implement immediately.
- Do not print or reread the complete diff; inspect only the edited regions once before writing the result.
- Implement production behavior through the existing Blender Main/WASM command routes; do not simulate Blender behavior in JavaScript.
- Do not run tests, builds, typecheck, lint, Chromium, full validators, or coverage binding. The user explicitly deferred verification to real usage.
- Do not modify docs/EXECUTION_QUEUE.md, nextTask.md, source coverage ledgers, manifests, or this backlog.
@@ -220,6 +222,8 @@ def run_task(task: dict, heartbeat_seconds: float) -> tuple[int, bool]:
"--ephemeral", "--cd", str(ROOT), "--json", "-",
]
completed_turn = False
result_seen_at: float | None = None
task_started_at = time.monotonic()
with log_path.open("w", encoding="utf-8") as log:
process = subprocess.Popen(
command,
@@ -238,6 +242,8 @@ def run_task(task: dict, heartbeat_seconds: float) -> tuple[int, bool]:
write_status(read_json(BACKLOG), "implementing", activeTask=task["id"], childPid=process.pid, log=str(log_path.relative_to(ROOT)))
log.flush()
if result_path.is_file():
if result_seen_at is None:
result_seen_at = time.monotonic()
try:
with log_path.open("rb") as current_log:
end = current_log.seek(0, os.SEEK_END)
@@ -245,6 +251,8 @@ def run_task(task: dict, heartbeat_seconds: float) -> tuple[int, bool]:
completed_turn = b'"type":"turn.completed"' in current_log.read()
except OSError:
completed_turn = False
if time.monotonic() - result_seen_at >= 5:
completed_turn = True
if completed_turn:
try:
os.killpg(process.pid, signal.SIGTERM)
@@ -255,6 +263,16 @@ def run_task(task: dict, heartbeat_seconds: float) -> tuple[int, bool]:
os.killpg(process.pid, signal.SIGKILL)
process.wait()
break
if time.monotonic() - task_started_at >= 900:
try:
os.killpg(process.pid, signal.SIGTERM)
process.wait(timeout=5)
except ProcessLookupError:
pass
except subprocess.TimeoutExpired:
os.killpg(process.pid, signal.SIGKILL)
process.wait()
break
time.sleep(heartbeat_seconds)
code = 0 if completed_turn else (process.returncode or 0)
ACTIVE_PROCESS = None

View File

@@ -11,6 +11,10 @@ const arg = (name, fallback = null) => {
const index = process.argv.indexOf(name);
return index >= 0 ? process.argv[index + 1] : fallback;
};
if (process.argv.includes("--help")) {
process.stdout.write("usage: node tools/web/search-wbv2-batch-source.mjs [--task <task-id>] --pattern <text> [--runtime <path> ...] or --list\n");
process.exit(0);
}
const task = arg("--task") ?? read("docs/EXECUTION_QUEUE.md").match(/\| 当前任务 \| `([^`]+)` \|/u)?.[1];
const pattern = arg("--pattern");
if (!task) throw new Error("unable to resolve current WBV2 task");