fix(task-agent): address Copilot review on the id projection

- wire_safe_tool_call_id: SHA-256 not SHA-1 for the deterministic token —
  matches the codebase convention for fingerprints (attachments, auth,
  session) and drops the SHA-1 scanner flag. Non-crypto use, ids unchanged
  in shape (tid_ + 32 hex); no test pins the literal value.
- interactive.js: the two sub-agent child-id example comments now show the
  real minted shape (<parent>::r{run}s{step}::<id>), not a stale <seq> form.

(cherry picked from commit a5c3dc00fc)
This commit is contained in:
Patrick Buckley
2026-07-10 19:43:43 -07:00
parent 3ef3f24c7f
commit be662c6134
2 changed files with 4 additions and 4 deletions
+2 -2
View File
@@ -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]]:
+2 -2
View File
@@ -653,7 +653,7 @@ class Pane {
if (!el) {
let target = this._toolRow(callId);
if (!target) {
// A minted sub-agent child id ("<parent>::<seq>::<id>") whose row hasn't
// A minted sub-agent child id ("<parent>::r{run}s{step}::<id>") 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 ("<parent>::<seq>::<id>") whose row hasn't
// A minted sub-agent child id ("<parent>::r{run}s{step}::<id>") 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.