- _budget_notice no longer names the cite tool after prepare_tools has
withdrawn it; the post-grace state gets the plain no-tools text back.
- Split search-budget rejections from any failed tool call: the code tool
raises ToolFailed for every error in model-written Python, so
budget_spent was true for a ZeroDivisionError.
- docs/capabilities/rag.md described the old single-turn removal.
- Drop the rationale clause from the CHANGELOG entry.
50 executions across 40 cases in an 822-case run died on
'_io.TextIOWrapper' object is not iterable, and those cases scored 37.5%
judged against 60.1% and cited 12.5% against 55.2%.
The pool watchdog counts only the time a worker spends running code, so a read
that blocks the worker never trips it. The margin above code_timeout therefore
guarded a race that cannot happen, and only bought a runaway call 90s where 60s
was configured. Pass code_timeout straight through. The two limits are disjoint:
the watchdog bounds a call that computes, and the read deadline bounds a call
that reads.
Drop the ordering test, which was true for any positive margin. The containment
test no longer sets code_timeout to zero, because that value now also disables
the watchdog and kills the worker before the read guard can refuse. It patches
the guard instead.
Monty 0.0.19 runs a plain class and a class with __enter__ and __exit__. Only
inheritance and metaclasses raise. Say that in the instructions.
MemoryFile is no longer constructed, so drop the import, the annotation, and the
stale references in the sandbox docstring and CLAUDE.md. That CLAUDE.md line
also still claimed a ThreadPoolExecutor, _run_async, and a fresh interpreter per
call.
Monty 0.0.19 supports open() and with blocks, but a file object is still not
iterable. See pydantic/monty#490, which is still open. The instructions now
state the limitation in three places and give the alternative next to each
one: readlines() or read().split("\n").
Replace chr(10) with "\n" in the prose and in the example. Both work on
0.0.19, and chr(10) implies that the escape is broken.
Add a test that pins the limitation. The test fails when Monty gains
iteration support, which is the signal to relax the instructions.
Document files can be read with open() and with-blocks (.read(),
.readline(), .readlines()); writes raise PermissionError. File objects
remain non-iterable and the collections module is still unavailable.
0.0.19 runs sandboxed code in a subprocess worker pool (AsyncMonty /
AsyncMontySession) and drops MontyRepl. The sandbox checks out a session,
drives it with feed_run, and closes it to return the worker; close() is
now async. Worker crashes surface as a failed SandboxResult. The document
VFS (OSAccess/CallbackFile/MemoryFile) is unchanged.