diff --git a/tests/cli/test_frontend_sandbox.py b/tests/cli/test_frontend_sandbox.py index 189bee32a..8cd52670f 100644 --- a/tests/cli/test_frontend_sandbox.py +++ b/tests/cli/test_frontend_sandbox.py @@ -17,6 +17,7 @@ from __future__ import annotations import asyncio +import ast import hmac import json import re @@ -24,8 +25,10 @@ from collections.abc import AsyncIterator, Mapping from dataclasses import replace from hashlib import sha256 +from pathlib import Path from types import SimpleNamespace +import httpx import pytest from fastapi import FastAPI, HTTPException, Request from fastapi.testclient import TestClient @@ -72,6 +75,63 @@ ) +@pytest.mark.parametrize("is_vestack_deployment", [False, True]) +@pytest.mark.asyncio +async def test_hermes_cli_surface_configuration_isolated_by_deployment( + is_vestack_deployment: bool, + monkeypatch: pytest.MonkeyPatch, +) -> None: + # Evaluate the real CLI registration without booting Studio or cloud clients. + source = Path(frontend_sandbox.__file__).with_name("cli_frontend.py") + tree = ast.parse(source.read_text()) + registrations = [ + node.value + for node in ast.walk(tree) + if isinstance(node, ast.Assign) + and any( + isinstance(target, ast.Name) and target.id == "sandbox_agent_services" + for target in node.targets + ) + ] + assert len(registrations) == 1 + registration = registrations[0] + hermes_call = next( + value + for key, value in zip(registration.keys, registration.values) + if isinstance(key, ast.Constant) and key.value == "hermes" + ) + service = eval( + compile(ast.Expression(hermes_call), str(source), "eval"), + { + "SandboxAgentSessionService": SandboxAgentSessionService, + "sandbox_gateway": _FakeGateway(), + "sandbox_chat_hermes_tool_id": "tool-hermes", + "sandbox_chat_hermes_snapshot_tool_id": "tool-hermes-snapshot", + "hermes_managed_tool_spec": None, + "is_vestack_deployment": is_vestack_deployment, + "os": SimpleNamespace(getenv=lambda _: ""), + }, + ) + if is_vestack_deployment: + assert service.surface_path == "/proxy/4500/" + assert service._surface_ready_path == "/proxy/4500/" + assert "hermes dashboard" in service._surface_start_command + assert "--port 4500" in service._surface_start_command + else: + assert service.surface_path == "/hermes/" + assert service._surface_ready_path == "" + assert service._surface_start_command == "" + + def unexpected_http_client(*args, **kwargs): + pytest.fail("Public-cloud Hermes must not start or probe Dashboard") + + monkeypatch.setattr(httpx, "AsyncClient", unexpected_http_client) + created = await service.create("alice") + opened, token = await service.open(created.instance_id, "alice") + assert opened.instance_id == created.instance_id + assert token + + class _FakeCodex: def __init__(self, turns: list[str], *, fail: bool = False) -> None: self.thread_id = "thread-1" diff --git a/tests/cli/test_frontend_sandbox_options.py b/tests/cli/test_frontend_sandbox_options.py index 4eff4b068..1c3f94efd 100644 --- a/tests/cli/test_frontend_sandbox_options.py +++ b/tests/cli/test_frontend_sandbox_options.py @@ -168,7 +168,7 @@ def test_local_studio_mounts_snapshot_tools_into_sandbox_services() -> None: " tool_id=sandbox_chat_hermes_tool_id,\n" " snapshot_tool_id=sandbox_chat_hermes_snapshot_tool_id,\n" " managed_tool_spec=hermes_managed_tool_spec,\n" - ' surface_path="/proxy/4500/",\n' + ' surface_path="/proxy/4500/" if is_vestack_deployment else None,\n' ) in source diff --git a/veadk/cli/cli_frontend.py b/veadk/cli/cli_frontend.py index e28dfea25..a31cdc900 100644 --- a/veadk/cli/cli_frontend.py +++ b/veadk/cli/cli_frontend.py @@ -3501,15 +3501,17 @@ def _migration_creator(request: Request) -> str: tool_id=sandbox_chat_hermes_tool_id, snapshot_tool_id=sandbox_chat_hermes_snapshot_tool_id, managed_tool_spec=hermes_managed_tool_spec, - surface_path="/proxy/4500/", + surface_path="/proxy/4500/" if is_vestack_deployment else None, surface_start_command=( "if ! curl -fsS --max-time 2 http://127.0.0.1:4500/ " ">/dev/null 2>&1; then " "nohup /home/gem/.local/bin/hermes dashboard " "--host 127.0.0.1 --port 4500 --no-open " ">/home/gem/.hermes/dashboard.log 2>&1 & fi" + if is_vestack_deployment + else "" ), - surface_ready_path="/proxy/4500/", + surface_ready_path="/proxy/4500/" if is_vestack_deployment else "", unconfigured_message=( "管理员未配置 Hermes 模型或 IAM Role。" if hermes_managed_tool_spec is None