Skip to content

Commit 4f3169c

Browse files
Xiaoaier-Z-Lzhenguo.li
andauthored
fix(studio): isolate Hermes dashboard settings to VeStack (#1077)
* fix(studio): isolate Hermes dashboard settings to VeStack * test(studio): align Hermes surface assertion with deployment guard --------- Co-authored-by: zhenguo.li <zhenguo.li@bytedance.com>
1 parent 43ce978 commit 4f3169c

3 files changed

Lines changed: 65 additions & 3 deletions

File tree

tests/cli/test_frontend_sandbox.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,18 @@
1717
from __future__ import annotations
1818

1919
import asyncio
20+
import ast
2021
import hmac
2122
import json
2223
import re
2324
import time
2425
from collections.abc import AsyncIterator, Mapping
2526
from dataclasses import replace
2627
from hashlib import sha256
28+
from pathlib import Path
2729
from types import SimpleNamespace
2830

31+
import httpx
2932
import pytest
3033
from fastapi import FastAPI, HTTPException, Request
3134
from fastapi.testclient import TestClient
@@ -72,6 +75,63 @@
7275
)
7376

7477

78+
@pytest.mark.parametrize("is_vestack_deployment", [False, True])
79+
@pytest.mark.asyncio
80+
async def test_hermes_cli_surface_configuration_isolated_by_deployment(
81+
is_vestack_deployment: bool,
82+
monkeypatch: pytest.MonkeyPatch,
83+
) -> None:
84+
# Evaluate the real CLI registration without booting Studio or cloud clients.
85+
source = Path(frontend_sandbox.__file__).with_name("cli_frontend.py")
86+
tree = ast.parse(source.read_text())
87+
registrations = [
88+
node.value
89+
for node in ast.walk(tree)
90+
if isinstance(node, ast.Assign)
91+
and any(
92+
isinstance(target, ast.Name) and target.id == "sandbox_agent_services"
93+
for target in node.targets
94+
)
95+
]
96+
assert len(registrations) == 1
97+
registration = registrations[0]
98+
hermes_call = next(
99+
value
100+
for key, value in zip(registration.keys, registration.values)
101+
if isinstance(key, ast.Constant) and key.value == "hermes"
102+
)
103+
service = eval(
104+
compile(ast.Expression(hermes_call), str(source), "eval"),
105+
{
106+
"SandboxAgentSessionService": SandboxAgentSessionService,
107+
"sandbox_gateway": _FakeGateway(),
108+
"sandbox_chat_hermes_tool_id": "tool-hermes",
109+
"sandbox_chat_hermes_snapshot_tool_id": "tool-hermes-snapshot",
110+
"hermes_managed_tool_spec": None,
111+
"is_vestack_deployment": is_vestack_deployment,
112+
"os": SimpleNamespace(getenv=lambda _: ""),
113+
},
114+
)
115+
if is_vestack_deployment:
116+
assert service.surface_path == "/proxy/4500/"
117+
assert service._surface_ready_path == "/proxy/4500/"
118+
assert "hermes dashboard" in service._surface_start_command
119+
assert "--port 4500" in service._surface_start_command
120+
else:
121+
assert service.surface_path == "/hermes/"
122+
assert service._surface_ready_path == ""
123+
assert service._surface_start_command == ""
124+
125+
def unexpected_http_client(*args, **kwargs):
126+
pytest.fail("Public-cloud Hermes must not start or probe Dashboard")
127+
128+
monkeypatch.setattr(httpx, "AsyncClient", unexpected_http_client)
129+
created = await service.create("alice")
130+
opened, token = await service.open(created.instance_id, "alice")
131+
assert opened.instance_id == created.instance_id
132+
assert token
133+
134+
75135
class _FakeCodex:
76136
def __init__(self, turns: list[str], *, fail: bool = False) -> None:
77137
self.thread_id = "thread-1"

tests/cli/test_frontend_sandbox_options.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ def test_local_studio_mounts_snapshot_tools_into_sandbox_services() -> None:
168168
" tool_id=sandbox_chat_hermes_tool_id,\n"
169169
" snapshot_tool_id=sandbox_chat_hermes_snapshot_tool_id,\n"
170170
" managed_tool_spec=hermes_managed_tool_spec,\n"
171-
' surface_path="/proxy/4500/",\n'
171+
' surface_path="/proxy/4500/" if is_vestack_deployment else None,\n'
172172
) in source
173173

174174

veadk/cli/cli_frontend.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3501,15 +3501,17 @@ def _migration_creator(request: Request) -> str:
35013501
tool_id=sandbox_chat_hermes_tool_id,
35023502
snapshot_tool_id=sandbox_chat_hermes_snapshot_tool_id,
35033503
managed_tool_spec=hermes_managed_tool_spec,
3504-
surface_path="/proxy/4500/",
3504+
surface_path="/proxy/4500/" if is_vestack_deployment else None,
35053505
surface_start_command=(
35063506
"if ! curl -fsS --max-time 2 http://127.0.0.1:4500/ "
35073507
">/dev/null 2>&1; then "
35083508
"nohup /home/gem/.local/bin/hermes dashboard "
35093509
"--host 127.0.0.1 --port 4500 --no-open "
35103510
">/home/gem/.hermes/dashboard.log 2>&1 & fi"
3511+
if is_vestack_deployment
3512+
else ""
35113513
),
3512-
surface_ready_path="/proxy/4500/",
3514+
surface_ready_path="/proxy/4500/" if is_vestack_deployment else "",
35133515
unconfigured_message=(
35143516
"管理员未配置 Hermes 模型或 IAM Role。"
35153517
if hermes_managed_tool_spec is None

0 commit comments

Comments
 (0)