3 Commits

Author SHA1 Message Date
IronMurphy
9dd8e3e94b
fix(middleware): derive the externalized filename from the tool call id (#6107)
* fix(middleware): derive the externalized filename from the tool call id

_build_externalized_filename documents that the host-disk and sandbox paths
share it so both produce the identical naming scheme, but it used a random uuid
suffix and ignored tool_call_id: the same call got a different name every time,
so the two paths could not agree and externalizing one output twice left two
files behind. Derive the name from the call id instead, sanitised the same way
tool names are, and drop the now unused uuid import.

* fix(middleware): hash externalized call IDs and content

* fix(middleware): catch sandbox filename encoding failures

* fix(middleware): handle host output encoding failures

---------

Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-10-06 09:06:33 +08:00
Daoyuan Li
7c52d5a187
fix(middleware): isolate temporary files for concurrent tool outputs (#6150)
* fix(middleware): isolate temporary files for concurrent tool outputs

* docs: trim tool output middleware guidance

* fix(middleware): preserve output permissions and clarify crash cleanup

---------

Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
2026-10-01 20:17:13 +08:00
IronMurphy
5b83cb502c
fix(middleware): publish externalized outputs atomically (#6109)
* fix(middleware): publish externalized outputs atomically

_externalize reported failure with None but had already created the file, so a
write that failed part-way (disk full, interrupted request) left a truncated
file under the final name in the outputs directory. Write to a sibling temp file
and os.replace it into place, removing the temp file when the write fails.

* style: drop the unused pytest import from the externalize test
2026-10-01 10:52:48 +08:00