Gr1mmJ4w
e60ca1c6ca
fix(agent): stop the send-path repair from rewriting persisted history
...
`_canonicalize_api_tool_calls` promises copy-on-write in its own docstring
— "the persisted history is untouched" — and the call site repeats it:
"Operates on api_messages (the API copy) so the original conversation
history in `messages` is untouched."
The canonicalize branch keeps that promise (`tc = {**tc, "function": {...}}`).
The repair branch does not:
except Exception:
tc["function"]["arguments"] = _repair_tool_call_arguments(...)
`api_messages` is built with `msg.copy()` — a SHALLOW per-message copy — so
every `tool_calls` entry is the same dict object the persisted history
holds. Assigning into `tc["function"]` therefore writes through to the
stored turn. The sibling loop two lines above only touches `am["content"]`,
one level deep, which is why the aliasing never showed up there.
On the unrepairable path `_repair_tool_call_arguments` returns "{}", so
that write replaces the model's real arguments with an empty object in the
transcript. A stream that dies mid `write_file` loses the file content it
had already streamed — the reported symptom in #80498 , where a chapter
draft was silently reduced to `{}` and only a WARNING remained:
Unrepairable tool_call arguments for write_file — replaced with empty
object (was: {"content": "# 骨架-第25章\n> 承接...)
Mirror the canonicalize branch: build a new tool-call dict instead of
assigning into the shared one. The API copy still carries "{}" — the
repair's whole purpose is to never ship broken JSON — but the history keeps
what the model actually sent, so the transcript, session persistence and
any later retry still have it.
The in-place write was not an oversight in isolation: it predates the memo
refactor, which preserved it deliberately for byte-parity. The existing
`test_history_not_mutated` asserts exactly this invariant but restricts
itself to valid arguments, and its docstring records the gap — "(Malformed
args take the in-place repair path — pre-existing behavior)". That is why
a test file whose header already claims "the persisted history is never
mutated (copy-on-write preserved)" stayed green through the bug.
Four tests close it: history keeps the original bytes, the send copy is
still repaired, a broken call does not disturb its siblings, and repeated
sends stay lossless. On unpatched main three of them fail; the parity and
complexity tests are unaffected because the difference is only observable
when the history list is separate from the send copy — which is the shape
production uses.
Refs #80498
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com >
2026-08-07 16:57:11 +05:30
..
2026-07-29 15:28:15 -07:00
2026-08-05 12:42:46 +05:30
2026-07-29 13:10:23 -07:00
2026-08-04 00:12:45 +05:30
2026-07-01 01:36:34 -07:00
2026-07-29 18:55:10 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-06-10 20:45:16 -07:00
2026-08-01 16:42:51 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-04 15:44:50 -07:00
2026-07-29 15:37:24 -07:00
2026-07-29 13:10:23 -07:00
2026-07-15 07:47:18 -07:00
2026-07-29 13:10:23 -07:00
2026-07-01 17:00:30 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-07 16:56:37 +05:30
2026-07-29 13:10:23 -07:00
2026-08-03 23:01:03 +05:30
2026-07-29 13:10:23 -07:00
2026-08-02 22:15:20 +05:30
2026-08-07 16:56:37 +05:30
2026-07-29 13:10:23 -07:00
2026-08-02 20:12:50 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-27 21:10:51 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-31 23:16:58 -07:00
2026-08-02 11:52:59 +05:30
2026-08-07 16:57:11 +05:30
2026-07-29 13:10:23 -07:00
2026-06-27 11:43:08 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-22 12:02:40 -05:00
2026-07-29 13:10:23 -07:00
2026-07-29 15:37:24 -07:00
2026-07-31 22:53:20 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-22 08:11:40 -07:00
2026-08-02 16:16:36 -07:00
2026-07-29 13:10:23 -07:00
2026-07-23 08:19:14 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-22 08:13:41 -07:00
2026-08-06 02:22:08 +05:30
2026-06-21 11:34:47 -07:00
2026-07-29 13:10:23 -07:00
2026-08-02 22:15:20 +05:30
2026-06-25 12:56:05 -07:00
2026-07-29 15:37:24 -07:00
2026-08-07 13:24:56 +05:30
2026-07-29 13:10:23 -07:00
2026-08-02 16:16:36 -07:00
2026-08-02 16:16:36 -07:00
2026-07-29 13:10:23 -07:00
2026-08-02 16:16:36 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-31 23:16:58 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-31 23:16:58 -07:00
2026-07-29 13:10:23 -07:00
2026-06-07 22:09:45 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-07 14:13:32 +05:30
2026-07-29 13:10:23 -07:00
2026-07-23 19:44:35 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 21:30:53 -07:00
2026-08-04 11:00:04 +05:30
2026-07-29 18:55:10 -07:00
2026-08-03 19:08:09 +05:30
2026-08-04 11:35:06 -06:00
2026-08-04 13:12:24 +05:30
2026-07-17 13:08:46 -04:00
2026-07-29 13:10:23 -07:00
2026-07-31 22:32:48 -07:00
2026-07-12 03:00:53 -07:00
2026-08-04 13:20:15 +05:30
2026-08-04 23:33:39 +05:30
2026-08-04 23:33:39 +05:30
2026-07-29 13:10:23 -07:00
2026-08-03 15:56:39 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-31 22:34:57 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-03 18:21:17 +05:30
2026-08-03 20:43:38 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-02 21:48:06 -07:00
2026-07-29 13:10:23 -07:00
2026-08-03 21:53:13 +05:30
2026-07-29 13:10:23 -07:00
2026-08-04 19:35:57 +00:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-01 14:27:12 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-19 14:58:59 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-05 17:21:01 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-03 18:45:43 +05:30
2026-07-29 13:10:23 -07:00
2026-08-02 22:15:20 +05:30
2026-05-28 00:20:11 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-06 22:14:52 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 21:30:53 -07:00
2026-08-03 17:53:55 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-06-19 15:23:41 +08:00
2026-07-29 12:29:39 -07:00
2026-07-31 23:18:12 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-01 14:27:12 +05:30
2026-07-01 06:02:33 -07:00
2026-08-03 22:43:15 +05:30
2026-07-23 16:17:27 -07:00
2026-07-29 13:10:23 -07:00
2026-07-23 18:40:09 -07:00
2026-07-29 13:10:23 -07:00
2026-07-23 18:40:09 -07:00
2026-07-29 13:10:23 -07:00
2026-07-23 16:17:27 -07:00
2026-06-30 03:39:50 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-04 11:08:32 +05:30
2026-07-29 15:12:28 -07:00
2026-08-02 22:47:48 +05:30
2026-07-29 19:48:37 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-09 21:10:07 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 15:37:24 -07:00
2026-07-29 07:47:06 +10:00
2026-08-02 15:01:11 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-03 22:55:36 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 15:37:24 -07:00
2026-08-06 02:22:08 +05:30
2026-08-06 02:22:08 +05:30
2026-08-03 21:12:56 +05:30
2026-07-29 19:48:37 -07:00
2026-08-01 15:39:58 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-10 05:41:59 -05:00
2026-07-29 13:10:23 -07:00
2026-08-06 22:02:37 -05:00
2026-08-01 15:58:25 +05:30
2026-08-05 22:40:51 -07:00
2026-07-31 21:52:35 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-21 12:11:31 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-02 10:02:33 -07:00
2026-08-02 09:59:52 -07:00
2026-08-02 16:16:36 -07:00
2026-07-22 10:00:39 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-31 07:30:30 -07:00
2026-07-29 13:10:23 -07:00
2026-07-31 07:30:30 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-02 22:15:20 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-03 20:43:34 +05:30
2026-07-29 10:14:11 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-30 21:07:36 +05:30
2026-07-28 03:54:16 -05:00
2026-07-29 13:10:23 -07:00
2026-08-03 23:23:39 +05:30
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-06 23:08:23 -05:00
2026-07-29 15:37:24 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-20 13:04:12 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-08-03 17:53:55 +05:30
2026-07-29 13:10:23 -07:00
2026-07-31 23:18:12 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-31 22:31:09 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-16 04:23:12 -07:00
2026-07-29 19:48:37 -07:00
2026-07-24 15:55:08 -07:00
2026-07-29 13:10:23 -07:00
2026-08-03 20:43:38 +05:30
2026-07-29 13:10:23 -07:00
2026-06-30 00:59:29 -05:00
2026-07-29 13:10:23 -07:00
2026-07-29 13:10:23 -07:00
2026-07-29 18:55:10 -07:00