"""旧任务接续 goal 模式:host.py goal-resume --goal-text。 已终局的旧任务没有 goal 记录是正常情况,--goal-text 模式跳过 状态与记录守卫,在旧线程上从第 1 轮开新目标循环(新语义: 无验收、不传轮次时不限轮次,模型宣告完成才结束)。 """ import json import os import sys import tempfile import unittest from pathlib import Path from unittest import mock REPO_ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(REPO_ROOT)) import host class FakeServer(object): def __init__(self, text): self.text = text self.resumed = [] def initialize(self): pass def close(self): pass def resume_thread(self, thread_id): self.resumed.append(thread_id) def run_turn(self, thread_id, prompt, model=None, effort=None, sandbox=None, timeout=None): return {"status": "completed", "text": self.text, "turn_id": "u1"} class GoalResumeTextTest(unittest.TestCase): def _run_main(self, task, goal_text): with tempfile.TemporaryDirectory() as tmp: state_path = os.path.join(tmp, "host-state.json") cfg_path = os.path.join(tmp, "host-config.json") with open(state_path, "w", encoding="utf-8") as f: json.dump({"tasks": {"g": task}, "automations": []}, f) with open(cfg_path, "w", encoding="utf-8") as f: json.dump({}, f) fake = FakeServer("done\n目标已达成") argv = ["host.py", "--state", state_path, "--config", cfg_path, "goal-resume", "--task", "g"] if goal_text is not None: argv += ["--goal-text", goal_text] with mock.patch.object(sys, "argv", argv): with mock.patch.object(host, "Server", lambda **kw: fake): host.main() with open(state_path, encoding="utf-8") as f: saved = json.load(f)["tasks"]["g"] return saved, fake def test_goal_text_init_on_completed_task(self): task = {"name": "g", "thread_id": "x", "cwd": "/tmp", "sandbox": None, "max_retries": 0, "retry_count": 0, "turns": [], "status": "completed"} saved, fake = self._run_main(task, "new goal") self.assertEqual(saved["status"], "goal-met") self.assertEqual(saved["goal"], "new goal") self.assertEqual(saved["goal_rounds_done"], 1) self.assertEqual(fake.resumed, ["x"]) def test_goal_text_refuses_task_without_thread(self): task = {"name": "g", "cwd": "/tmp", "sandbox": None, "max_retries": 0, "retry_count": 0, "turns": [], "status": "completed"} saved, fake = self._run_main(task, "new goal") self.assertEqual(saved["status"], "completed") self.assertEqual(fake.resumed, []) if __name__ == "__main__": unittest.main()