Adds two Camofox features: 1. Persistent browser sessions: new `browser.camofox.managed_persistence` config option. When enabled, Hermes sends a deterministic profile-scoped userId to Camofox so the server maps it to a persistent browser profile directory. Cookies, logins, and browser state survive across restarts. Default remains ephemeral (random userId per session). 2. VNC URL discovery: Camofox /health endpoint returns vncPort when running in headed mode. Hermes constructs the VNC URL and includes it in navigate responses so the agent can share it with users. Also fixes camofox_vision bug where call_llm response object was passed directly to json.dumps instead of extracting .choices[0].message.content. Changes from original PR: - Removed browser_evaluate tool (separate feature, needs own PR) - Removed snapshot truncation limit change (unrelated) - Config.yaml only for managed_persistence (no env var, no version bump) - Rewrote tests to use config mock instead of env var - Reverted package-lock.json churn Co-authored-by: analista <psikonetik@gmail.com.com>
48 lines
1.6 KiB
Python
48 lines
1.6 KiB
Python
"""Hermes-managed Camofox state helpers.
|
|
|
|
Provides profile-scoped identity and state directory paths for Camofox
|
|
persistent browser profiles. When managed persistence is enabled, Hermes
|
|
sends a deterministic userId derived from the active profile so that
|
|
Camofox can map it to the same persistent browser profile directory
|
|
across restarts.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import uuid
|
|
from pathlib import Path
|
|
from typing import Dict, Optional
|
|
|
|
from hermes_constants import get_hermes_home
|
|
|
|
CAMOFOX_STATE_DIR_NAME = "browser_auth"
|
|
CAMOFOX_STATE_SUBDIR = "camofox"
|
|
|
|
|
|
def get_camofox_state_dir() -> Path:
|
|
"""Return the profile-scoped root directory for Camofox persistence."""
|
|
return get_hermes_home() / CAMOFOX_STATE_DIR_NAME / CAMOFOX_STATE_SUBDIR
|
|
|
|
|
|
def get_camofox_identity(task_id: Optional[str] = None) -> Dict[str, str]:
|
|
"""Return the stable Hermes-managed Camofox identity for this profile.
|
|
|
|
The user identity is profile-scoped (same Hermes profile = same userId).
|
|
The session key is scoped to the logical browser task so newly created
|
|
tabs within the same profile reuse the same identity contract.
|
|
"""
|
|
scope_root = str(get_camofox_state_dir())
|
|
logical_scope = task_id or "default"
|
|
user_digest = uuid.uuid5(
|
|
uuid.NAMESPACE_URL,
|
|
f"camofox-user:{scope_root}",
|
|
).hex[:10]
|
|
session_digest = uuid.uuid5(
|
|
uuid.NAMESPACE_URL,
|
|
f"camofox-session:{scope_root}:{logical_scope}",
|
|
).hex[:16]
|
|
return {
|
|
"user_id": f"hermes_{user_digest}",
|
|
"session_key": f"task_{session_digest}",
|
|
}
|