mirror of
https://github.com/AstrBotDevs/AstrBot.git
synced 2026-10-16 15:06:04 +08:00
* fix: reject unresolvable image references instead of faking a local path A plugin can hand over a media reference such as `/api/v1/files/tokens/<token>`. Neither an existing file nor a valid payload, it was still returned as a local file, so `to_path()` resolved it into a path that does not exist on disk (on Windows `C:\api\v1\files\tokens\<token>`). That fabricated path reached `req.image_urls` and the prompt, and the real failure only surfaced later as a warning while preparing model images. `_materialize_media_ref()` now enforces its own contract: - A reference that exists but is not a regular file (directory, FIFO, socket, device) raises ValueError for every media family. - Image references must resolve to an existing file, URL or base64 payload. Images are read right after resolution, so a missing source is a failure rather than a file that may appear later. - Audio, video and generic file references keep returning a local path that does not exist yet: `ensure_wav()` and the STT retry loop rely on that for platform races such as NapCat handing over a voice path before it is readable. Supporting changes: - `to_base64_data(strict=False)` still degrades to `None` when an image ref cannot be materialized, which payload assembly relies on to skip bad refs. - `describe_media_ref()` reports unresolved refs as such instead of calling them a local media path. - Unavailable image warnings now include the original reference. Refs #10264 * fix: keep pathlib tolerance for over-long and non-regular media refs `_materialize_media_ref()` replaced `path.exists()` with a bare `path.stat()` and caught only OSError. pathlib's `exists()` also swallows ValueError, which Windows raises for paths past the 32767 character limit and for embedded NUL bytes. A bare base64 payload longer than that limit failed with `ValueError: stat: path too long for Windows` instead of being decoded, and audio/video/file references lost the pending-path behaviour for the same input. `to_base64_data()` had the matching gap: it caught only OSError around resolution, so a directory or empty reference escaped as ValueError even in non-strict mode. Payload assembly (openai/anthropic/gemini sources) relies on `None` there to skip one bad image instead of failing the whole request, and `is_recoverable_image_error()` already classifies ValueError as recoverable. Both sites now catch what pathlib and the module's own recovery predicate treat as a missing or unusable local file. Regression tests cover an oversized bare base64 image, an oversized pending audio path, and directory/empty references through the non-strict image path. * docs: describe the media reference error contract precisely Review feedback on the pull request: - `_materialize_media_ref()` only raises FileNotFoundError for a missing file URI when the reference is an image. Audio, video and file references return the pending path instead, which the `Raises:` section now states instead of reading as if it applied to every media family. - `Image.convert_to_file_path()` can raise ValueError as well: for an existing non-regular path, and already for an empty url/file before this branch. Docstrings only, no behaviour change.