diff --git a/turnstone/core/lowering.py b/turnstone/core/lowering.py index c40c548e..d339b46d 100644 --- a/turnstone/core/lowering.py +++ b/turnstone/core/lowering.py @@ -308,7 +308,7 @@ _WIRE_TOOL_ID_RE = re.compile(r"[a-zA-Z0-9_-]{1,40}") def wire_safe_tool_call_id(tc_id: str) -> str: """Return *tc_id* unchanged if it already matches the conservative wire-legal shape (:data:`_WIRE_TOOL_ID_RE`), else a deterministic safe - token (``tid_`` + 32 hex chars of its SHA-1, 36 chars total). + token (``tid_`` + 32 hex chars of its SHA-256, 36 chars total). Determinism is the contract: the same original id maps to the same token in the assistant ``tool_use`` and its ``tool_result`` (intra-request @@ -320,7 +320,7 @@ def wire_safe_tool_call_id(tc_id: str) -> str: """ if _WIRE_TOOL_ID_RE.fullmatch(tc_id): return tc_id - return "tid_" + hashlib.sha1(tc_id.encode("utf-8", "surrogatepass")).hexdigest()[:32] + return "tid_" + hashlib.sha256(tc_id.encode("utf-8", "surrogatepass")).hexdigest()[:32] def legalize_tool_call_ids(messages: list[dict[str, Any]]) -> list[dict[str, Any]]: diff --git a/turnstone/shared_static/interactive.js b/turnstone/shared_static/interactive.js index 956e8eff..1954530b 100644 --- a/turnstone/shared_static/interactive.js +++ b/turnstone/shared_static/interactive.js @@ -653,7 +653,7 @@ class Pane { if (!el) { let target = this._toolRow(callId); if (!target) { - // A minted sub-agent child id ("::::") whose row hasn't + // A minted sub-agent child id ("::r{run}s{step}::") whose row hasn't // nested yet must NOT graft its stream onto the last top-level batch — // that mislabels a sub-tool's output as a main-harness tool's. Its row // arrives via the orphan flush; skip the chunk until then. @@ -3491,7 +3491,7 @@ class Pane { } let target = this._toolRow(callId); if (!target) { - // A minted sub-agent child id ("::::") whose row hasn't + // A minted sub-agent child id ("::r{run}s{step}::") whose row hasn't // nested yet must NOT graft its output onto the last top-level batch row // — that mislabels a sub-tool's result as a main-harness tool's. Its row // arrives via the orphan flush; skip until then.