fix duplicate chat upload filenames
This commit is contained in:
committed by
nesquena-hermes
parent
0c6af12723
commit
0f388de09c
@@ -13,6 +13,7 @@
|
||||
- Sidebar compression lineage collapse now prefers the current continuation tip over a preserved parent snapshot when both rows share the same backend segment count. This keeps reloads after context compression from reopening the older parent transcript and making the active conversation appear to disappear.
|
||||
- Reloading a stale `/session/<parent>` compression URL now resolves to the visible continuation tip from the sidebar payload instead of reopening the archived parent snapshot.
|
||||
- Undo, retry, and explicit session truncation now persist a sidecar truncation watermark, preventing older `state.db` rows from reappearing after the WebUI transcript was intentionally shortened.
|
||||
- Chat uploads with the same filename in one session now keep distinct attachment files instead of overwriting the earlier upload.
|
||||
|
||||
## [v0.51.136] — 2026-05-25 — Release DH (stage-batch18 — 5-PR streaming + session index batch)
|
||||
|
||||
|
||||
@@ -81,6 +81,16 @@ def _upload_destination(session_id: str, safe_name: str) -> Path:
|
||||
dest = (dest_dir / safe_name).resolve()
|
||||
if not dest.is_relative_to(dest_dir):
|
||||
raise ValueError('Invalid upload destination')
|
||||
if dest.exists():
|
||||
stem = dest.stem
|
||||
suffix = dest.suffix
|
||||
for idx in range(1, 1000):
|
||||
candidate = (dest_dir / f'{stem}-{idx}{suffix}').resolve()
|
||||
if not candidate.is_relative_to(dest_dir):
|
||||
raise ValueError('Invalid upload destination')
|
||||
if not candidate.exists():
|
||||
return candidate
|
||||
raise ValueError('Too many uploads with the same filename')
|
||||
return dest
|
||||
|
||||
|
||||
|
||||
@@ -352,6 +352,24 @@ def test_upload_respects_attachment_dir_env(monkeypatch, tmp_path):
|
||||
assert _session_attachment_dir("session-123") == inbox.resolve() / "session-123"
|
||||
|
||||
|
||||
def test_upload_destination_does_not_overwrite_same_filename(monkeypatch, tmp_path):
|
||||
"""Repeated uploads with the same filename in one session keep distinct paths."""
|
||||
from api.upload import _upload_destination
|
||||
|
||||
inbox = tmp_path / "attachment-inbox"
|
||||
monkeypatch.setenv("HERMES_WEBUI_ATTACHMENT_DIR", str(inbox))
|
||||
|
||||
first = _upload_destination("session-123", "photo.png")
|
||||
first.write_bytes(b"first")
|
||||
second = _upload_destination("session-123", "photo.png")
|
||||
second.write_bytes(b"second")
|
||||
|
||||
assert first.name == "photo.png"
|
||||
assert second.name == "photo-1.png"
|
||||
assert first.read_bytes() == b"first"
|
||||
assert second.read_bytes() == b"second"
|
||||
|
||||
|
||||
def test_upload_too_large(cleanup_test_sessions):
|
||||
"""Uploading a file over MAX_UPLOAD_BYTES is rejected (413 or connection closed)."""
|
||||
sid, _ = make_session_tracked(cleanup_test_sessions)
|
||||
|
||||
Reference in New Issue
Block a user