ajuste no contas

This commit is contained in:
T3782834
2026-09-01 11:24:03 -03:00
parent 9ed4782f9d
commit 397b831fd3
428 changed files with 2294 additions and 4648 deletions

View File

@@ -295,3 +295,31 @@ def test_json_pending_writes_remain_plain_json() -> None:
persisted = repo.saved[1]
assert persisted["pending_writes"][0]["value"] == {"ok": True}
def test_stale_pending_write_cannot_replace_newer_checkpoint() -> None:
"""A delayed write for cp1 must never make cp1 latest after cp2 exists."""
repo = _Repo()
saver = RepositoryCheckpointSaver(SimpleNamespace(), repository=repo)
cfg0 = {"configurable": {"thread_id": "tx-thread"}}
cp1_cfg = asyncio.run(saver.aput(cfg0, {"id": "cp1", "v": 1, "channel_values": {"transaction_status": "COMPLETED"}}, {}, {}))
cp2_cfg = asyncio.run(saver.aput(cp1_cfg, {"id": "cp2", "v": 1, "channel_values": {"transaction_status": "AWAITING_CONFIRMATION", "confirmation_required": True}}, {}, {}))
# Simulates aput_writes from the older cp1 finishing after cp2 was persisted.
asyncio.run(saver.aput_writes(cp1_cfg, [("result", {"old": True})], "late-task"))
assert repo.saved is not None
latest = repo.saved[1]
assert latest["checkpoint_id"] == "cp2"
assert latest["checkpoint"]["channel_values"]["transaction_status"] == "AWAITING_CONFIRMATION"
assert "pending_writes" not in latest or not any(
isinstance(item, dict) and item.get("task_id") == "late-task"
for item in latest.get("pending_writes", [])
)
# A write for the actual latest checkpoint is still accepted.
asyncio.run(saver.aput_writes(cp2_cfg, [("result", {"new": True})], "current-task"))
latest = repo.saved[1]
assert latest["checkpoint_id"] == "cp2"
assert any(item.get("task_id") == "current-task" for item in latest.get("pending_writes", []))

View File

@@ -188,3 +188,31 @@ def test_snapshot_interrupts_deduplicates_task_and_persisted_shapes(tmp_path: Pa
)
assert runtime._snapshot_interrupts(snapshot) == [payload]
@pytest.mark.asyncio
async def test_aresume_ignores_stale_interrupt_after_advancing_to_terminal_node(tmp_path: Path, monkeypatch):
_write_workflow(tmp_path)
runtime = WorkflowRuntime(FileWorkflowRepository(tmp_path), actions=WorkflowActionRegistry())
state = _terminal_state("exec-stale")
# Shape observed after resuming invoice_explanation: the durable snapshot can
# still expose the interrupt from the old pause although current_node has
# already advanced to the terminal handoff/finalization node.
stale = SimpleNamespace(value={"node": "old_pause", "prompt": "old prompt"})
task = SimpleNamespace(interrupts=(stale,))
snapshot = SimpleNamespace(next=("finish__continue",), tasks=(task,), values=state)
monkeypatch.setattr(runtime, "_compile", lambda definition: _FakeGraph(state, snapshot))
langgraph_module = ModuleType("langgraph")
types_module = ModuleType("langgraph.types")
class _Command:
def __init__(self, **kwargs):
self.kwargs = kwargs
types_module.Command = _Command
monkeypatch.setitem(sys.modules, "langgraph", langgraph_module)
monkeypatch.setitem(sys.modules, "langgraph.types", types_module)
result = await runtime.aresume("terminal", "exec-stale", "nao")
assert result.status == "COMPLETED"
assert result.pause is None
assert result.state["current_node"] == "finish"