* perf(media): preload visible chat videos * fix(media): ignore detached visibility callbacks * fix(ui): require provable live owner for live-turn preservation (#6948) A completed assistant turn could render twice: when the stream ended (S.activeStreamId cleared) but INFLIGHT[sid] was not yet cleaned, the preserve guard treated bare rendered content (.msg-body presence) as proof of liveness and re-attached the stale live DOM node OVER the rebuilt settled transcript — a second copy of the same message. Data was always clean (state.db, sidecar, /api/session each hold one row); the duplicate existed only in the rendered DOM. Preserve the live turn across the wipe only while there is a provable live owner: an active stream (S.activeStreamId, the #3877 mid-stream case) or explicit live-assistant evidence in the current message projection (S.messages carrying a client-side _live / _activityBurstId / _liveSegmentSeq marker — the reconnect/terminal-projection case). A settled transcript has neither, so the durable settled render wins and appears exactly once. The #5390 blank-turn guard (对话消失) is preserved: a dead empty shell has no live projection either and is still dropped. * changelog: exp batch — #7109 double-render fix + #7076 video preload --------- Co-authored-by: allenliang2022 <allenliang2022@users.noreply.github.com> Co-authored-by: webtecnica <webtecnica@gmail.com> Co-authored-by: n <a@n> Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
This commit is contained in:
4 files changed
+400
-57
No files matched your search
@@ -5,6 +5,10 @@
|
||||
|
||||
### Fixed
|
||||
|
||||
- **A completed assistant turn no longer renders twice in the feed.** In `renderMessages()`, the live-turn preserve guard kept the in-flight assistant node across the DOM rebuild whenever it held any rendered content, so when a stream ended but its inflight bookkeeping was not yet cleared the just-completed turn was re-attached over the rebuilt settled transcript (a first copy without the model label, then a second with it). The stored data was always clean (state.db, sidecar, and `/api/session` each hold one row) — the duplicate existed only in the DOM. Preservation now requires a provable live owner (`S.activeStreamId` or explicit live-projection markers) instead of bare DOM content; the mid-stream flicker guard and blank-turn guard are preserved. Thanks @webtecnica. (#7109)
|
||||
|
||||
- **Visible inline chat videos no longer appear stalled after metadata.** Every inline video stayed at `preload="metadata"`, so a currently-visible mobile player could look frozen because the browser stops loading after metadata. A shared IntersectionObserver now promotes a near-viewport video to `preload="auto"` (and immediately on play), keeps off-screen history videos at metadata to avoid buffering every historical video, and unobserves nodes removed before they intersect. No media URL, caching, or controls change. Thanks @allenliang2022. (#7076)
|
||||
|
||||
- **Profile goal contract no longer drifts across profiles on older agent builds.** On Hermes Agent builds where the context-override API was exposed but `SessionDB()` still used the import-time default DB path (v2026.5.28–v2026.7.20), a goal mutation in one profile could overwrite another profile's goal. Native profile-goal persistence is now gated on the agent supporting *both* context-home resolution *and* call-time DB-path selection; otherwise it falls back to the legacy per-profile manager. Profiles stay isolated. Thanks @ticketclosed-won. (#6899)
|
||||
|
||||
- **Packaged `hermes-webui` console entry point.** `pip install`-style wheel installs now expose a `hermes-webui` command that boots the WebUI through `bootstrap:main` — the same launcher path as `python server.py`, so agent-interpreter discovery and dependency validation run before the server starts (a direct `server:main` entry started the UI but broke every chat with a missing-dependency error). Thanks @webtecnica. (#6742)
|
||||
|
||||
Reference in new issue
Block a user