Repository navigation
fix(messages): absolutise local audio and video paths in markdown output - #1833
Merged
Merged
Conversation
Yunnglin
approved these changes
Oct 10, 2026
Yunnglin
left a comment
Collaborator
There was a problem hiding this comment.
LGTM — minimal, well-tested consistency fix that restores markdown/structured-chain parity for local audio/video paths; verified the new tests fail without it and the related suite (87) passes. Thanks!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this fixes
messages_to_markdownrenders local media differently depending on the content type. TheContentImagebranch resolves a local file to an absolute path and skipsmax_lengthtruncation; theContentAudioandContentVideobranches do neither, so:max_lengthtruncates a real path into a prefix that no longer exists.Evidence that this is an oversight, not a dialect difference
970e9518, "fix(web): render local-path media in both dashboard chains") introduced theos.path.isfile/os.path.abspathhandling, but only in theContentImagebranch of this same function._absolutize_media_path(evalscope/report/data_frames.py:262), whose docstring says it "mirrors whatmessages_to_markdowndoes for the markdown chain, so both chains expose local media the same way". That mirror claim only holds for images:_MEDIA_BLOCK_TYPEScoversimage/audio/video, and the structured chain absolutises all three.web/src/utils/media.tsdocumentsresolveMediaSrcas "shared by both rendering chains so that a local media path shows up the same way in structuredContentBlockmessages and in Markdown text".ContentAudio.audio/ContentVideo.videoare documented as "Audio file path or base64 encoded data URL" / "Video file path, URL, or base64 encoded data URL" — a path is a supported value for both.Repro (real code path, before this change)
Sample.pretty_print(evalscope/api/dataset/dataset.py:77) defaults tomax_length=50, which is shorter than most paths, and is called fromevaluator.py:515.Change
Guard the audio and video branches with
os.path.isfile, the same way the image branch already does. Non-file values (base64 payloads,data:URIs, http(s) URLs, missing files) keep their previous behaviour.Verification
tests/api/test_messages_to_markdown.py: 5 added, 10 pass."<video controls src='/private/t'></video>"); with the fix restored, 10 pass. The fifth (test_base64_audio_and_video_are_still_truncated_by_max_length) passes both ways and pins the unchanged base64 behaviour.max_lengthvalues x 3 roles x with / without a reasoning block). Snapshots were taken on the fixed tree and on the reverted tree using a probe that only calls the real function and contains no logic of its own: 1950 identical, 480 changed, 0 unintended. Every change is a local-file value gaining its absolute path; no non-file value changed at all.tests/api/test_messages_to_markdown.py,tests/report/test_prediction_media_paths.py,tests/api/test_io_utils.py,tests/api/test_dataset_loader.py,tests/api/test_default_data_adapter.py: 87 passed.ruff checkandruff format --checkclean.Stored-data impact
messages_to_markdownoutput is written into prediction caches and report text, so this does change what gets persisted. Analysed separately: that markdown is display-only — nothing in the repository parses the emitted path back out (agrepforcontrols srcfinds only the two producers). Existing entries stay readable as they are; the change only makes future entries point at the same file through an absolute path instead of a relative or already-truncated one. No migration is needed.