fix: preserve company resume control and agent identity

This commit is contained in:
LZH-YS1998
2026-07-14 16:59:24 +08:00
parent b8202bbe9e
commit 297295a4aa
12 changed files with 2459 additions and 123 deletions
+79 -1
View File
@@ -802,6 +802,24 @@ async def test_resume_candidates_use_nonterminal_work_item_over_terminal_task(
"phase": Phase.RUNNING.value,
}
],
"task_snapshots": [
{
"task_id": task.id,
"status": TaskStatus.DONE.value,
"assigned_to": "executor",
"assigned_external_agent": "",
"selected_execution_agent": "native",
"work_item_id": work_item.work_item_id,
"work_item": {
"work_item_id": work_item.work_item_id,
"phase": Phase.RUNNING.value,
"role_id": "executor",
"seat_id": "seat::executor",
"role_runtime_session_id": "",
"metadata": {},
},
}
],
},
resume_task_ids={task.id},
)
@@ -1062,7 +1080,9 @@ async def test_successful_checkpoint_handoff_reopens_cancelled_ui_anchor(
await store.save_execution_checkpoint(checkpoint)
engine = OPCEngine(project_id="project-a")
engine.store = store
engine.company_executor = SimpleNamespace()
engine.company_executor = SimpleNamespace(
_notify_kanban_changed=AsyncMock(),
)
engine._prepare_company_runtime_tasks_for_resume = AsyncMock(
return_value=[runtime_task]
)
@@ -1087,6 +1107,7 @@ async def test_successful_checkpoint_handoff_reopens_cancelled_ui_anchor(
handed_off_tasks, driver_ownership = handed_off
assert handed_off_tasks == [runtime_task]
assert driver_ownership is not None
engine.company_executor._notify_kanban_changed.assert_awaited_once_with()
driver_ownership.release()
assert still_cancelled is not None
assert still_cancelled.status == TaskStatus.CANCELLED
@@ -1110,6 +1131,63 @@ async def test_successful_checkpoint_handoff_reopens_cancelled_ui_anchor(
await store.close()
@_async_test
async def test_failed_checkpoint_handoff_does_not_publish_running_snapshot(
tmp_path: Path,
) -> None:
store = OPCStore(tmp_path / "tasks.db")
await store.initialize()
try:
runtime_task = _runtime_task(
task_id="runtime-task",
status=TaskStatus.BLOCKED,
)
await store.save_task(runtime_task)
checkpoint = ExecutionCheckpoint(
project_id="project-a",
session_id="root-session",
checkpoint_type="company_runtime_interrupted",
task_id=runtime_task.id,
payload={
"task_ids": [runtime_task.id],
"parent_session_id": "root-session",
},
)
await store.save_execution_checkpoint(checkpoint)
engine = OPCEngine(project_id="project-a")
engine.store = store
engine.company_executor = SimpleNamespace(
_notify_kanban_changed=AsyncMock(),
)
engine._prepare_company_runtime_tasks_for_resume = AsyncMock(
side_effect=RuntimeError("prepare failed"),
)
with pytest.raises(RuntimeError, match="prepare failed"):
await engine._handoff_company_suspend_checkpoint(
checkpoint,
payload=dict(checkpoint.payload),
parent_session_id="root-session",
tasks=[runtime_task],
)
engine.company_executor._notify_kanban_changed.assert_not_awaited()
assert not engine._active_task_run_registry.is_active(
"project-a",
runtime_task.id,
)
pending = await store.get_execution_checkpoints(
project_id="project-a",
session_id="root-session",
checkpoint_types=["company_runtime_interrupted"],
statuses=["pending"],
)
assert len(pending) == 1
assert pending[0].payload.get("resume_state") == "failed_before_handoff"
finally:
await store.close()
@_async_test
async def test_executor_failure_restores_pending_checkpoint_and_durable_holds(
tmp_path: Path,