v2 rehearsal: FLAG-3 order note-before-notice on first-turn co-pending (fix effective order, pin with test)
This commit is contained in:
1 parent
6a70775ad9
commit
adc2a02f6c
2 files changed
+40
-9
No files matched your search
@@ -504,6 +504,33 @@ class HostLoopTestCase(unittest.TestCase):
|
|||||||
self.assertIn("new goal", prompts[0])
|
self.assertIn("new goal", prompts[0])
|
||||||
self.assertIn("旧目标", prompts[0])
|
self.assertIn("旧目标", prompts[0])
|
||||||
|
|
||||||
|
def test_first_turn_both_pending_note_before_notice(self):
|
||||||
|
# FLAG-3 定序(v2 演练决定):首轮断点备注与改 goal 通知
|
||||||
|
# 同 pending 时,模型可见顺序为备注在前、通知在后。
|
||||||
|
# 注意代码里两次 prepend 的执行顺序与可见顺序相反
|
||||||
|
# (先贴通知、再贴备注),本测试钉住的是可见顺序,
|
||||||
|
# 而非执行顺序。
|
||||||
|
task = self._task()
|
||||||
|
self._write_signal(1, "new goal")
|
||||||
|
prompts = []
|
||||||
|
script = [("completed", "目标已达成", None)]
|
||||||
|
fake = _fake_turn_script(prompts, script)
|
||||||
|
note = ("[审计推回包(第 1 轮)]\n"
|
||||||
|
"- [execution_failed] 证据:boom detail")
|
||||||
|
with mock.patch.object(host_mod, "run_task_turn", fake):
|
||||||
|
result = host_mod.run_goal_loop(
|
||||||
|
SimpleNamespace(), self.state, self.state_path, task,
|
||||||
|
"old goal", None, 0, None, None, None, cfg=None,
|
||||||
|
resume_note=note)
|
||||||
|
self.assertTrue(result["ok"])
|
||||||
|
self.assertEqual(result["rounds_done"], 1)
|
||||||
|
self.assertEqual(len(prompts), 1)
|
||||||
|
first = prompts[0]
|
||||||
|
self.assertTrue(first.startswith(note))
|
||||||
|
self.assertLess(first.index(note), first.index("目标已更新"))
|
||||||
|
self.assertIn("new goal", first)
|
||||||
|
self.assertIn("作废", first)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
@@ -2915,21 +2915,25 @@ def run_goal_loop(server, state, state_path, task, goal_text, verify,
|
|||||||
f"目标:{goal_text}\n"
|
f"目标:{goal_text}\n"
|
||||||
f"验收命令:{verify_text}\n"
|
f"验收命令:{verify_text}\n"
|
||||||
f"上一轮验收输出:\n{last_verify}")
|
f"上一轮验收输出:\n{last_verify}")
|
||||||
|
# FLAG-3 定序(v2 演练决定):首轮两者同 pending 时,
|
||||||
|
# 模型可见顺序为断点备注在前、改 goal 通知在后、再是
|
||||||
|
# 本轮任务提示。注意两次 prepend 的执行顺序与可见顺序
|
||||||
|
# 相反:先贴通知、再贴备注,最终才是备注在前。v1 注释
|
||||||
|
# 声称“先见备注”但代码实际产生通知在前,v2 在此修正,
|
||||||
|
# 并由 test_goal_live_update 的共 pending 测试钉住。
|
||||||
|
# 影响面仅首轮共 pending 时;之后轮次备注块是 no-op,
|
||||||
|
# 通知块行为不变。
|
||||||
|
if pending_goal_notice is not None:
|
||||||
|
# 本轮提示显式写出旧 goal → 新 goal;通知只用一次,
|
||||||
|
# 下一轮提示是重新构造的,不重复贴。
|
||||||
|
prompt = pending_goal_notice + "\n\n" + prompt
|
||||||
|
pending_goal_notice = None
|
||||||
# N-12:断点备注只贴第一轮 prompt(见 _first_turn 注释),
|
# N-12:断点备注只贴第一轮 prompt(见 _first_turn 注释),
|
||||||
# 绝不写回 goal_text——task["goal"] 在循环开始时已按原
|
# 绝不写回 goal_text——task["goal"] 在循环开始时已按原
|
||||||
# goal_text 落盘,备注只是本次续跑的展示前缀。
|
# goal_text 落盘,备注只是本次续跑的展示前缀。
|
||||||
if _first_turn and resume_note:
|
if _first_turn and resume_note:
|
||||||
prompt = "%s\n\n%s" % (resume_note, prompt)
|
prompt = "%s\n\n%s" % (resume_note, prompt)
|
||||||
_first_turn = False
|
_first_turn = False
|
||||||
# 演练注 FLAG:与上同锚点——运行中改 goal 的旧→新通知
|
|
||||||
# 与 N-12 断点备注同属 prompt 前缀;两段独立 flag,
|
|
||||||
# 并集保留(备注在前、改 goal 通知在后);若首轮两者
|
|
||||||
# 同 pending,模型先见备注后见改 goal 通知,顺序待定。
|
|
||||||
if pending_goal_notice is not None:
|
|
||||||
# 本轮提示显式写出旧 goal → 新 goal;通知只用一次,
|
|
||||||
# 下一轮提示是重新构造的,不重复贴。
|
|
||||||
prompt = pending_goal_notice + "\n\n" + prompt
|
|
||||||
pending_goal_notice = None
|
|
||||||
try:
|
try:
|
||||||
result = run_task_turn(server, state, task, prompt,
|
result = run_task_turn(server, state, task, prompt,
|
||||||
model, effort, sandbox, timeout=timeout,
|
model, effort, sandbox, timeout=timeout,
|
||||||
|
|||||||
Reference in new issue
Block a user