b7eb97a835
_download_image() and _download_video() both used client.get() + response.content, buffering the entire media body into memory before checking the size cap. A server that omits Content-Length could send an arbitrarily large payload, causing OOM. Extract _stream_download_to_file() shared helper: streams via client.stream() + aiter_bytes(), writes chunks to a temp file, enforces the running byte count against the cap after each chunk, and atomically replaces onto the destination on success. Cleans up the temp file on failure. Uses utils.atomic_replace() for cross-device/symlink safety. Malformed Content-Length values are now caught and ignored instead of crashing with ValueError; the streaming cap is the authoritative guard. Approach adapted from PR #10440 by @WuKongAI-CMU (closed as stale — 14923 commits behind, reverted 32 commits of vision_tools.py evolution including SSRF-safe client, retry classification, and lazy imports). Closes #10440