docs: v0.50.41 CHANGELOG, version bump, test count (1117)
This commit is contained in:
33
CHANGELOG.md
33
CHANGELOG.md
@@ -1,5 +1,38 @@
|
|||||||
# Hermes Web UI -- Changelog
|
# Hermes Web UI -- Changelog
|
||||||
|
|
||||||
|
## [v0.50.41] feat(ui): render MEDIA: images inline in web UI chat (fixes #450)
|
||||||
|
|
||||||
|
When the agent outputs `MEDIA:<path>` tokens — screenshots from the browser tool,
|
||||||
|
generated images, vision outputs — the web UI now renders them **inline in the chat**,
|
||||||
|
the same way Claude.ai handles images. No more relaying screenshots through Telegram.
|
||||||
|
|
||||||
|
**How it works:**
|
||||||
|
- Local image path (`MEDIA:/tmp/screenshot.png`): rendered as `<img>` via `/api/media?path=...`
|
||||||
|
- HTTP(S) URL to image (`MEDIA:https://example.com/img.png`): `<img>` directly from the URL
|
||||||
|
- Non-image file (`MEDIA:/tmp/report.pdf`): styled download link (📎 filename)
|
||||||
|
- Click any inline image to toggle full-size zoom
|
||||||
|
|
||||||
|
**New endpoint — `GET /api/media?path=<encoded-path>`:**
|
||||||
|
- Path allowlist: `~/.hermes/`, `/tmp/`, active workspace — covers all agent output locations
|
||||||
|
- Auth-gated: requires valid session cookie when auth is enabled
|
||||||
|
- Inline image MIME types: PNG, JPEG, GIF, WebP, BMP
|
||||||
|
- SVG always served as download attachment (XSS prevention)
|
||||||
|
- RFC 5987-compliant `Content-Disposition` headers (handles Unicode filenames)
|
||||||
|
- `Cache-Control: private, max-age=3600`
|
||||||
|
|
||||||
|
**Security:**
|
||||||
|
- Original version had `~` (entire home dir) as an allowed root — **fixed** by independent reviewer
|
||||||
|
- Restricted to `~/.hermes/`, `/tmp/`, and active workspace only
|
||||||
|
- `Path.resolve()` + `commonpath` checks prevent symlink traversal
|
||||||
|
|
||||||
|
**Changes:**
|
||||||
|
- `api/routes.py`: `_handle_media()` handler + `/api/media` route
|
||||||
|
- `static/ui.js`: `MEDIA:` stash in `renderMd()` (runs before `fence_stash`, stash token `\x00D`)
|
||||||
|
- `static/style.css`: `.msg-media-img` (480px max-width, zoom-on-click), `.msg-media-link`
|
||||||
|
- `tests/test_media_inline.py`: 19 new tests (static analysis + integration)
|
||||||
|
|
||||||
|
- Total tests: 1117 (was 1098)
|
||||||
|
|
||||||
## [v0.50.40] feat: session UI polish + parallel test isolation
|
## [v0.50.40] feat: session UI polish + parallel test isolation
|
||||||
|
|
||||||
**Session sidebar improvements:**
|
**Session sidebar improvements:**
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
> Prerequisites: SSH tunnel is active on port 8787. Open http://localhost:8787 in browser.
|
> Prerequisites: SSH tunnel is active on port 8787. Open http://localhost:8787 in browser.
|
||||||
> Server health check: curl http://127.0.0.1:8787/health should return {"status":"ok"}.
|
> Server health check: curl http://127.0.0.1:8787/health should return {"status":"ok"}.
|
||||||
>
|
>
|
||||||
> Automated tests: 1098 total (1098 passing, 0 known failures). Includes onboarding coverage for bootstrap/static wizard presence, real provider config persistence (`config.yaml` + `.env`), the `/api/onboarding/*` backend, and the onboarding skip/existing-config guard.
|
> Automated tests: 1117 total (1117 passing, 0 known failures). Includes onboarding coverage for bootstrap/static wizard presence, real provider config persistence (`config.yaml` + `.env`), the `/api/onboarding/*` backend, and the onboarding skip/existing-config guard.
|
||||||
> Run: `pytest tests/ -v --timeout=60`
|
> Run: `pytest tests/ -v --timeout=60`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -536,7 +536,7 @@
|
|||||||
<div class="settings-section-title">System</div>
|
<div class="settings-section-title">System</div>
|
||||||
<div class="settings-section-meta">Instance version and access controls.</div>
|
<div class="settings-section-meta">Instance version and access controls.</div>
|
||||||
</div>
|
</div>
|
||||||
<span class="settings-version-badge">v0.50.40</span>
|
<span class="settings-version-badge">v0.50.41</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-field" style="border-top:1px solid var(--border);padding-top:12px;margin-top:8px">
|
<div class="settings-field" style="border-top:1px solid var(--border);padding-top:12px;margin-top:8px">
|
||||||
<label for="settingsPassword" data-i18n="settings_label_password">Access Password</label>
|
<label for="settingsPassword" data-i18n="settings_label_password">Access Password</label>
|
||||||
|
|||||||
Reference in New Issue
Block a user