Fix/viewer stability#4
Open
PaoloC68 wants to merge 5 commits into
Open
Conversation
When execute.py runs outside /a0 cwd, the 'from usr.plugins...' import fails silently and falls back to a dummy resolve_camofox_command that always raises 'CamoFox CLI helper unavailable'. Prepending /a0 to sys.path makes the import succeed regardless of cwd.
vnc_session_key was set to int(vnc_ts * 1000), so every set_vnc() write produced a new key even when the upstream URL was unchanged. The WebUI store uses session_key to detect 'real' session changes — a timestamp- based key defeated that and caused the iframe to reload on every poll. Hashing the raw URL makes session_key represent session identity: it changes only when the actual upstream token changes.
Two bugs fixed: 1. _normalize_entry() cleared vnc_url after _VNC_IDLE_TTL_SECONDS even though the camofox server's VNC stack was still running. The URL should reflect server reality (set_vnc/clear_vnc), not a wall-clock heuristic. After ~1h idle the iframe vanished mid-session. 2. get(user_id) returned a strict per-user lookup. The WebUI resolves to 'a0-default' (no agent context) while agent tools resolve to 'a0-agent-N'. Once the store cached _userId='a0-default', it kept asking for that user even after browsing moved to 'a0-agent-0'. Now get() falls back to any active user when the requested one is idle, so the viewer always sees the live session. Also bumps _VNC_IDLE_TTL_SECONDS comment to reflect that the value is now effectively unused for clearing (kept for browsing staleness only).
showBrowser() called toggle-display whenever this.vncUrl was null, even if the server was already running in virtual/headed mode and the WebUI just hadn't received the URL via poll yet. Each toggle cycle stops VNC, closes the persistent context, relaunches, and starts a fresh VNC — ~3 seconds of darkness during which the iframe loses its source and on reconnect grabs keyboard focus. Now if displayMode is virtual/headed or _rawVncUrl is set, just reveal the panel and force a poll instead of toggling.
x-if destroys and recreates the DOM element when its condition flips. During the inevitable ~3s gap between 'vnc stopped' and 'vnc started' on a toggle (or any momentary null vnc_url), the iframe was torn out of the DOM. When the URL returned, a fresh iframe was built, noVNC autoconnected, and the new iframe stole focus. x-show only toggles CSS display, so the iframe element persists across gaps. The placeholder now also gates on _rawVncUrl so it only shows for sessions that have never received a URL.
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.
This PR fixes five distinct bugs that together cause the CamoFox VNC viewer iframe to disappear, reload every few seconds, and steal keyboard focus from the Agent Zero chat input — eventually making the WebUI unusable until the plugin is disabled. All five are reproducible on a fresh install of Agent Zero + this plugin.
Debugged collaboratively with a user on a long session; root-causes traced end-to-end with server logs, state file inspection, and live DevTools console probing. Each commit is self-contained and explains its own fix.
Bugs fixed
1.
execute.py— silent CLI helper fallback (commitd87f44a)When
execute.pyruns outside/[a0](https://helpa0.com/#)as cwd,from usr.plugins.camofox_browser.helpers.cli import resolve_camofox_commandfails silently and falls back to a stub that always raisesRuntimeError("CamoFox CLI helper unavailable"). Setup step 7 fails with no useful diagnostic. Fix: prepend/[a0](https://helpa0.com/#)tosys.pathbefore the import.2.
viewer_url.py—vnc_session_keyderived from timestamp (commit92aa7b3)vnc_session_key = int(vnc_ts * 1000)changes on everyset_vnc()write. The WebUI store usessession_keyto detect real session changes — a timestamp-based key defeats this and causes the iframe to be reloaded on every 3-second poll, generating a new signed JWT each time. Fix: hash the raw upstream URL — session_key now represents session identity.3.
state.py—_normalize_entryclearing livevnc_urlafter idle TTL (commit815a6b4, part 1)The worst of the bunch.
_normalize_entry()wipesvnc_urlwhenvnc_age > _VNC_IDLE_TTL_SECONDS(10 s by default!) even though the camofox server's VNC stack is still running. The URL should reflect server reality, not a wall-clock heuristic. After 10 s of "idle" the iframe vanishes mid-session. Fix: remove the time-based clearing. URL changes only via explicitset_vnc()/clear_vnc().4.
state.py—get(user_id)strict per-user lookup (commit815a6b4, part 2)The WebUI has no agent context so
resolve_user_id()returns"a0-default", while agent tools resolve to"a0-agent-N". Once the store caches_userId="a0-default", it keeps asking for that user even after browsing has moved toa0-agent-0. Result: emptyvnc_url, no iframe. Fix:get()falls back to any active user when the requested one is idle.5.
camofox-store.js—showBrowser()toggles even when server already visible (commitd269c23)if (this.vncUrl) return;is the only early-out. If the WebUI'svncUrlis null but the server is already invirtualmode, clicking the browser button triggers a full toggle cycle (stop VNC → close persistent context → relaunch → start VNC = ~3 s downtime) for no reason. Fix: ifdisplayModeisvirtual/headedor_rawVncUrlis set, just reveal the panel and force a poll.6.
camofox-browser-btn.html— iframe wrapped inx-if(commita3111ce)x-ifdestroys and recreates DOM on every state flip. During the inevitable null-URL gap on any toggle, the iframe is torn out of the DOM and the placeholder briefly flashes. When the URL returns, a fresh iframe is built, noVNC autoconnects, and the new iframe steals keyboard focus — making chat input impossible. Fix: usex-showfor the iframe (DOM persists, only CSS toggles). Placeholder also gates on_rawVncUrlto suppress flashes.Test plan
Agent Zeroinstance with this plugin enabledcamofox_browseaction → iframe should appearNotes for the maintainer
_VNC_IDLE_TTL_SECONDSconstant since it's still used for browsing-staleness logic; just stopped using it to wipe URLs.CC: full debug session preserved if you want any specific scenario walked through.