fix: address PR review round 4 — remove web UI, fix audio/import/interface issues
Remove web UI gateway (web.py, tests, docs, toolset, env vars, Platform.WEB enum) per maintainer request — Nous is building their own official chat UI. Fix 1: Replace sd.wait() with polling pattern in play_audio_file() to prevent indefinite hang when audio device stalls (consistent with play_beep()). Fix 2: Use importlib.util.find_spec() for faster_whisper/openai availability checks instead of module-level imports that trigger heavy native library loading (CUDA/cuDNN) at import time. Fix 3: Remove inspect.signature() hack in _send_voice_reply() — add **kwargs to Telegram send_voice() so all adapters accept metadata uniformly. Fix 4: Make session loading resilient to removed platform enum values — skip entries with unknown platforms instead of crashing the entire gateway.
This commit is contained in:
parent
1ad5e0ed15
commit
35748a2fb0
17 changed files with 55 additions and 2930 deletions
|
|
@ -829,13 +829,6 @@ class GatewayRunner:
|
|||
return None
|
||||
return EmailAdapter(config)
|
||||
|
||||
elif platform == Platform.WEB:
|
||||
from gateway.platforms.web import WebAdapter, check_web_requirements
|
||||
if not check_web_requirements():
|
||||
logger.warning("Web: aiohttp not installed. Run: pip install aiohttp")
|
||||
return None
|
||||
return WebAdapter(config)
|
||||
|
||||
return None
|
||||
|
||||
def _is_user_authorized(self, source: SessionSource) -> bool:
|
||||
|
|
@ -855,11 +848,6 @@ class GatewayRunner:
|
|||
if source.platform == Platform.HOMEASSISTANT:
|
||||
return True
|
||||
|
||||
# Web UI users are authenticated via token at the WebSocket level.
|
||||
# No additional allowlist check needed.
|
||||
if source.platform == Platform.WEB:
|
||||
return True
|
||||
|
||||
user_id = source.user_id
|
||||
if not user_id:
|
||||
return False
|
||||
|
|
@ -978,7 +966,7 @@ class GatewayRunner:
|
|||
"personality", "retry", "undo", "sethome", "set-home",
|
||||
"compress", "usage", "insights", "reload-mcp", "reload_mcp",
|
||||
"update", "title", "resume", "provider", "rollback",
|
||||
"background", "reasoning", "voice", "remote-control", "remote_control"}
|
||||
"background", "reasoning", "voice"}
|
||||
if command and command in _known_commands:
|
||||
await self.hooks.emit(f"command:{command}", {
|
||||
"platform": source.platform.value if source.platform else "",
|
||||
|
|
@ -1053,10 +1041,6 @@ class GatewayRunner:
|
|||
if command == "voice":
|
||||
return await self._handle_voice_command(event)
|
||||
|
||||
if command in ("remote-control", "remote_control"):
|
||||
return await self._handle_remote_control_command(event)
|
||||
|
||||
|
||||
# User-defined quick commands (bypass agent loop, no LLM call)
|
||||
if command:
|
||||
quick_commands = self.config.get("quick_commands", {})
|
||||
|
|
@ -1741,7 +1725,6 @@ class GatewayRunner:
|
|||
"`/rollback [number]` — List or restore filesystem checkpoints",
|
||||
"`/background <prompt>` — Run a prompt in a separate background session",
|
||||
"`/voice [on|off|tts|status]` — Toggle voice reply mode",
|
||||
"`/remote-control [port] [token]` — Start web UI for remote access",
|
||||
"`/reload-mcp` — Reload MCP servers from config",
|
||||
"`/update` — Update Hermes Agent to the latest version",
|
||||
"`/help` — Show this message",
|
||||
|
|
@ -2415,10 +2398,6 @@ class GatewayRunner:
|
|||
}
|
||||
if event.source.thread_id:
|
||||
send_kwargs["metadata"] = {"thread_id": event.source.thread_id}
|
||||
import inspect
|
||||
sig = inspect.signature(adapter.send_voice)
|
||||
if "metadata" not in sig.parameters:
|
||||
send_kwargs.pop("metadata", None)
|
||||
await adapter.send_voice(**send_kwargs)
|
||||
except Exception as e:
|
||||
logger.warning("Auto voice reply failed: %s", e, exc_info=True)
|
||||
|
|
@ -2488,62 +2467,6 @@ class GatewayRunner:
|
|||
)
|
||||
return f"❌ {result['error']}"
|
||||
|
||||
async def _handle_remote_control_command(self, event: MessageEvent) -> str:
|
||||
"""Handle /remote-control — start or show the web UI for remote access."""
|
||||
from gateway.config import Platform, PlatformConfig
|
||||
|
||||
is_dm = event.source and event.source.chat_type == "dm"
|
||||
|
||||
# Already running?
|
||||
if Platform.WEB in self.adapters:
|
||||
adapter = self.adapters[Platform.WEB]
|
||||
local_ip = adapter._get_local_ip()
|
||||
token_display = adapter._token if is_dm else "(hidden — use in DM to see token)"
|
||||
return (
|
||||
f"Web UI already running.\n"
|
||||
f"URL: http://{local_ip}:{adapter._port}\n"
|
||||
f"Token: {token_display}"
|
||||
)
|
||||
|
||||
# Start web adapter on the fly
|
||||
try:
|
||||
from gateway.platforms.web import WebAdapter, check_web_requirements
|
||||
if not check_web_requirements():
|
||||
return "Web UI requires aiohttp. Run: pip install aiohttp"
|
||||
|
||||
args = event.get_command_args().strip()
|
||||
port = 8765
|
||||
token = ""
|
||||
for part in args.split():
|
||||
if part.isdigit():
|
||||
port = int(part)
|
||||
elif part and not part.startswith("-"):
|
||||
token = part
|
||||
|
||||
web_config = PlatformConfig(
|
||||
enabled=True,
|
||||
extra={"port": port, "host": "127.0.0.1", "token": token},
|
||||
)
|
||||
adapter = WebAdapter(web_config)
|
||||
adapter.set_message_handler(self._handle_message)
|
||||
|
||||
success = await adapter.connect()
|
||||
if not success:
|
||||
return f"Failed to start Web UI on port {port}. Port may be in use."
|
||||
|
||||
self.adapters[Platform.WEB] = adapter
|
||||
local_ip = adapter._get_local_ip()
|
||||
token_display = adapter._token if is_dm else "(hidden — use in DM to see token)"
|
||||
return (
|
||||
f"Web UI started!\n"
|
||||
f"URL: http://{local_ip}:{adapter._port}\n"
|
||||
f"Token: {token_display}\n"
|
||||
f"Open this URL on your phone or any device on the same network."
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error("Failed to start web UI: %s", e, exc_info=True)
|
||||
return f"Failed to start Web UI: {e}"
|
||||
|
||||
async def _handle_background_command(self, event: MessageEvent) -> str:
|
||||
"""Handle /background <prompt> — run a prompt in a separate background session.
|
||||
|
||||
|
|
@ -2607,7 +2530,6 @@ class GatewayRunner:
|
|||
Platform.SIGNAL: "hermes-signal",
|
||||
Platform.HOMEASSISTANT: "hermes-homeassistant",
|
||||
Platform.EMAIL: "hermes-email",
|
||||
Platform.WEB: "hermes-web",
|
||||
}
|
||||
platform_toolsets_config = {}
|
||||
try:
|
||||
|
|
@ -2629,7 +2551,6 @@ class GatewayRunner:
|
|||
Platform.SIGNAL: "signal",
|
||||
Platform.HOMEASSISTANT: "homeassistant",
|
||||
Platform.EMAIL: "email",
|
||||
Platform.WEB: "web",
|
||||
}.get(source.platform, "telegram")
|
||||
|
||||
config_toolsets = platform_toolsets_config.get(platform_config_key)
|
||||
|
|
@ -3517,7 +3438,6 @@ class GatewayRunner:
|
|||
Platform.SIGNAL: "hermes-signal",
|
||||
Platform.HOMEASSISTANT: "hermes-homeassistant",
|
||||
Platform.EMAIL: "hermes-email",
|
||||
Platform.WEB: "hermes-web",
|
||||
}
|
||||
|
||||
# Try to load platform_toolsets from config
|
||||
|
|
@ -3542,7 +3462,6 @@ class GatewayRunner:
|
|||
Platform.SIGNAL: "signal",
|
||||
Platform.HOMEASSISTANT: "homeassistant",
|
||||
Platform.EMAIL: "email",
|
||||
Platform.WEB: "web",
|
||||
}.get(source.platform, "telegram")
|
||||
|
||||
# Use config override if present (list of toolsets), otherwise hardcoded default
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue