chat: recover from V8 max-string-length when persisting session state (#319183)
* ObjectMutationLog: recover from V8 max-string-length on stringify JSON.stringify on the full session state (every 1024 mutations during compaction) could exceed V8's ~512 MiB max string length when extensions stored very large content in IChatAgentResult.metadata.toolCallResults (notably Copilot's read_page tool can produce ~60 MiB browser dumps). The thrown RangeError propagated up and lost the entire chat session. Wrap the JSON.stringify(entry) calls in ObjectMutationLog with a catch for RangeError that retries with a replacer truncating strings over 1 MiB and capping total at 100 MiB. The common path is a single JSON.stringify with zero overhead; only failures pay the recovery cost. Generic across the whole schema, so any future field that grows is also protected. Fixes #308843. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> (Written by Copilot) * Address review: rename _BYTES -> _CHARS, tighten total-budget check Copilot reviewer noted: - Constants were named _BYTES but track string.length (UTF-16 code units), and the 'guaranteed to succeed' claim ignored JSON escaping and keys. Renamed to _CHARS and clarified that the budget is approximate. - makeTruncatingReplacer checked total >= maxTotalChars *before* counting the current string, so one extra under-cap string could overshoot the cap. Now projects (total + val.length + 2) and emits the truncation marker if it would exceed the budget. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> (Written by Copilot)
R
Rob Lourens committed
eb308be4f9d2ce27a4117d84b7a789d90dd6cd62
Parent: 4918ed6
Committed by GitHub <noreply@github.com>
on 6/1/2026, 12:03:32 AM