31485d50ea
A degenerate tool name stored in conversation history (dots, spaces, unicode from an earlier model degeneration) bricks every subsequent Codex Responses turn with a non-retryable HTTP 400: Invalid input[N].name: string does not match pattern '^[a-zA-Z0-9_-]+' The 400 replays forever until the user manually starts a new session. Add _sanitize_replayed_fn_name() — replaces invalid chars with '_' (runs collapsed), degrades all-invalid names to 'fn' instead of empty (an empty name would trade one 400 for a preflight ValueError). Applied at both replay sites: the chat-message converter and the preflight choke-point. Live tool-definition names are left untouched — they must match the dispatch registry exactly. Pairing is by call_id, so renaming a replayed function_call is safe. call_id overflow (the sibling half of #49224) was already fixed on main by #73492 (_clamp_responses_call_id); this commit covers the remaining invalid-name defect. Credit: @Morad37 (#31678 — identified the bug, the replay sites, and the regex contract), @lubosxyz (#49224 — replace-not-strip semantics and 'fn' fallback to avoid the empty-name trap). Fixes #31666