From 6a594e8030347cfcdfdb0dfb962828d03e1b2efd Mon Sep 17 00:00:00 2001 From: alt-glitch Date: Wed, 7 Oct 2026 06:26:17 +0530 Subject: [PATCH] fix(agent): scripted prelude call ids are deterministic The prelude minted uuid4 call ids, against the sanitizer's hard invariant that call ids are deterministic and never uuid4 (they feed prompt-cache prefixes). It now uses deterministic_call_id, seeded by the card's name and arguments and its position in history: unique within a session, byte-stable on replay. --- agent/turn_scripted_prelude.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/agent/turn_scripted_prelude.py b/agent/turn_scripted_prelude.py index af376c9bb9..ca5ce90a8d 100644 --- a/agent/turn_scripted_prelude.py +++ b/agent/turn_scripted_prelude.py @@ -14,9 +14,10 @@ counted and no ``pre/post_api_request`` hook fires for a step. from __future__ import annotations -import uuid +import json from typing import Any, Generator, Optional, Tuple +from agent.message_sanitization import deterministic_call_id from agent.transports.types import NormalizedResponse, build_tool_call from agent.turn_tool_round import run_tool_round @@ -37,7 +38,9 @@ def run_scripted_prelude(agent: Any, s: Any, prelude: Prelude) -> Any: s.finish_reason = "tool_calls" s.assistant_message = NormalizedResponse( content=content, finish_reason="tool_calls", - tool_calls=[build_tool_call(f"call_{uuid.uuid4().hex[:24]}", name, args)]) + # Seeded by the card and its place in history: unique within the session, byte-stable on replay. + tool_calls=[build_tool_call(deterministic_call_id(name, json.dumps(args, sort_keys=True), len(s.messages)), + name, args)]) verdict = _run_phase(run_tool_round, agent, s) if verdict.action != "continue": break