Import AITURK IDE 1.0.0-beta.1 from Hermes 63279301; preserve MIT license
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
"""GUI capability follows the SESSION's client, not the backend's process env.
|
||||
|
||||
The desktop app is a client. It can drive a backend that Electron spawned
|
||||
locally, one reached over SSH, one behind a plain URL+token, or Hermes Cloud —
|
||||
and only the first two run with ``HERMES_DESKTOP=1`` in their environment.
|
||||
Gating the pane/browser/reaction tools on that env var therefore stripped every
|
||||
one of them from URL and cloud gateways, while the same backend still told the
|
||||
model "You are chatting inside the Hermes desktop app".
|
||||
|
||||
These tests pin the contract that replaced it: eligibility is resolved from the
|
||||
session's own ``source`` (``session.create``'s ``source: 'desktop'``), so the
|
||||
answer is identical on every connection topology.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
import tui_gateway.server as server
|
||||
from toolsets import TOOLSETS, resolve_toolset
|
||||
|
||||
GUI_TOOLS = {
|
||||
"annotate_preview",
|
||||
"desktop_preview",
|
||||
"drive_preview",
|
||||
"close_terminal",
|
||||
"focus_pane",
|
||||
"read_terminal",
|
||||
"read_window_below",
|
||||
"react_to_message",
|
||||
"setup_mcp",
|
||||
"show_tip",
|
||||
"gui_tour",
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def no_desktop_env(monkeypatch):
|
||||
"""A backend nobody told about the desktop — i.e. every remote gateway."""
|
||||
monkeypatch.delenv("HERMES_DESKTOP", raising=False)
|
||||
monkeypatch.delenv("HERMES_DESKTOP_TERMINAL", raising=False)
|
||||
monkeypatch.delenv("HERMES_TUI_TOOLSETS", raising=False)
|
||||
return monkeypatch
|
||||
|
||||
|
||||
class TestDesktopUiToolset:
|
||||
def test_holds_exactly_the_gui_affordances(self):
|
||||
# apply_layout registers into desktop_ui via the registry (not the
|
||||
# static toolsets.py list), so force discovery first — otherwise the
|
||||
# result depends on which earlier test imported tool modules
|
||||
# (pre-existing ordering flake, surfaced by the #97979 test sweep).
|
||||
from tools.registry import discover_builtin_tools
|
||||
discover_builtin_tools()
|
||||
assert set(resolve_toolset("desktop_ui")) == GUI_TOOLS | {"apply_layout"}
|
||||
|
||||
def test_stays_off_the_core_tool_list(self):
|
||||
"""Core ships on every API call — a GUI-only tool must not be there."""
|
||||
from toolsets import _HERMES_CORE_TOOLS
|
||||
|
||||
assert GUI_TOOLS.isdisjoint(_HERMES_CORE_TOOLS)
|
||||
|
||||
def test_no_platform_bundle_carries_it(self):
|
||||
"""Messaging/CLI bundles must not pick these up by listing them."""
|
||||
for name, spec in TOOLSETS.items():
|
||||
if name == "desktop_ui":
|
||||
continue
|
||||
assert GUI_TOOLS.isdisjoint(set(spec.get("tools") or ())), name
|
||||
|
||||
|
||||
class TestSurfaceResolution:
|
||||
def test_desktop_session_gets_them_with_no_desktop_env(self, no_desktop_env):
|
||||
"""THE regression: a desktop client on a remote/cloud backend."""
|
||||
assert "desktop_ui" in server._gui_surface_toolsets("desktop")
|
||||
|
||||
def test_tui_session_does_not(self, no_desktop_env):
|
||||
assert "desktop_ui" not in server._gui_surface_toolsets("tui")
|
||||
|
||||
def test_desktop_env_alone_does_not_grant_them(self, no_desktop_env):
|
||||
"""A desktop-spawned backend serving a TUI session stays clean.
|
||||
|
||||
The embedded terminal pane runs `hermes --tui` against this same
|
||||
backend; env-keyed gating handed it GUI tools it cannot answer.
|
||||
"""
|
||||
no_desktop_env.setenv("HERMES_DESKTOP", "1")
|
||||
assert "desktop_ui" not in server._gui_surface_toolsets("tui")
|
||||
|
||||
def test_project_tools_ride_on_every_gui_surface(self, no_desktop_env):
|
||||
for platform in ("desktop", "tui"):
|
||||
assert "project" in server._gui_surface_toolsets(platform)
|
||||
|
||||
|
||||
class TestResolverPlumbing:
|
||||
def test_posture_path_folds_in_the_session_surface(self, no_desktop_env):
|
||||
"""Focus-mode returns early — the surface toolsets must survive it."""
|
||||
import agent.coding_context as cc
|
||||
|
||||
no_desktop_env.setattr(cc, "coding_selection", lambda **_: ["coding"])
|
||||
|
||||
assert server._load_enabled_toolsets("desktop") == [
|
||||
"coding",
|
||||
"desktop_ui",
|
||||
"project",
|
||||
]
|
||||
assert server._load_enabled_toolsets("tui") == ["coding", "project"]
|
||||
|
||||
def test_config_path_folds_in_the_session_surface(self, no_desktop_env):
|
||||
import agent.coding_context as cc
|
||||
import hermes_cli.config as config_mod
|
||||
|
||||
no_desktop_env.setattr(cc, "coding_selection", lambda **_: None)
|
||||
no_desktop_env.setattr(
|
||||
config_mod, "load_config", lambda: {"platform_toolsets": {"cli": ["memory"]}}
|
||||
)
|
||||
|
||||
desktop = server._load_enabled_toolsets("desktop")
|
||||
tui = server._load_enabled_toolsets("tui")
|
||||
|
||||
assert desktop is not None and tui is not None
|
||||
assert "desktop_ui" in desktop
|
||||
assert "desktop_ui" not in tui
|
||||
|
||||
def test_explicit_env_pin_still_wins(self, no_desktop_env):
|
||||
"""HERMES_TUI_TOOLSETS is an operator override; surface can't re-add."""
|
||||
no_desktop_env.setenv("HERMES_TUI_TOOLSETS", "web,memory")
|
||||
|
||||
assert server._load_enabled_toolsets("desktop") == ["web", "memory"]
|
||||
Reference in New Issue
Block a user