make bridge worker transport configurable (#1106)
This commit is contained in:
@@ -12,6 +12,9 @@ const PREVIEW_HOME_DIR_NAME = 'hermes-web-ui-pereview-home'
|
||||
const PREVIEW_BACKEND_PORT = 8650
|
||||
const PREVIEW_FRONTEND_PORT = 8651
|
||||
const PREVIEW_AGENT_BRIDGE_PORT = 18650
|
||||
const PREVIEW_AGENT_BRIDGE_WORKER_PORT_BASE = 19650
|
||||
const PREVIEW_AGENT_BRIDGE_ENDPOINT_ENV = 'HERMES_WEB_UI_PREVIEW_AGENT_BRIDGE_ENDPOINT'
|
||||
const PREVIEW_AGENT_BRIDGE_TRANSPORT_ENV = 'HERMES_WEB_UI_PREVIEW_AGENT_BRIDGE_TRANSPORT'
|
||||
const PREVIEW_FRONTEND_URL = `http://localhost:${PREVIEW_FRONTEND_PORT}`
|
||||
const PREVIEW_TAG_REF_PATTERN = /^[A-Za-z0-9._/-]+$/
|
||||
const PREVIEW_MAIN_REF = 'main'
|
||||
@@ -207,12 +210,43 @@ function getPreviewHomeDir() {
|
||||
return join(getWebUiHome(), PREVIEW_HOME_DIR_NAME)
|
||||
}
|
||||
|
||||
function normalizePreviewAgentBridgeTransport(value: string | undefined) {
|
||||
const transport = value?.trim().toLowerCase()
|
||||
return transport && ['tcp', 'ipc', 'unix'].includes(transport) ? transport : ''
|
||||
}
|
||||
|
||||
function getPreviewAgentBridgeEndpoint() {
|
||||
return process.platform === 'win32'
|
||||
const configured = process.env[PREVIEW_AGENT_BRIDGE_ENDPOINT_ENV]?.trim()
|
||||
if (configured) return configured
|
||||
|
||||
const transport = normalizePreviewAgentBridgeTransport(process.env[PREVIEW_AGENT_BRIDGE_TRANSPORT_ENV])
|
||||
|| normalizePreviewAgentBridgeTransport(process.env.HERMES_AGENT_BRIDGE_WORKER_TRANSPORT)
|
||||
const useTcp = transport ? transport === 'tcp' : process.platform === 'win32'
|
||||
return useTcp
|
||||
? `tcp://127.0.0.1:${PREVIEW_AGENT_BRIDGE_PORT}`
|
||||
: `ipc://${join(getPreviewHomeDir(), 'agent-bridge.sock')}`
|
||||
}
|
||||
|
||||
function getTcpEndpointPort(endpoint: string): number | null {
|
||||
try {
|
||||
const url = new URL(endpoint)
|
||||
if (url.protocol !== 'tcp:') return null
|
||||
const port = Number(url.port)
|
||||
return Number.isInteger(port) && port > 0 && port <= 65535 ? port : null
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
function getPreviewListeningPorts() {
|
||||
const agentBridgePort = getTcpEndpointPort(getPreviewAgentBridgeEndpoint())
|
||||
return [
|
||||
PREVIEW_BACKEND_PORT,
|
||||
PREVIEW_FRONTEND_PORT,
|
||||
...(agentBridgePort ? [agentBridgePort] : []),
|
||||
]
|
||||
}
|
||||
|
||||
function getPreviewPackagePath() {
|
||||
return join(getPreviewDir(), 'package.json')
|
||||
}
|
||||
@@ -315,11 +349,7 @@ function parsePidLines(output: string): number[] {
|
||||
}
|
||||
|
||||
function getPreviewListeningPids(): number[] {
|
||||
const ports = [
|
||||
PREVIEW_BACKEND_PORT,
|
||||
PREVIEW_FRONTEND_PORT,
|
||||
...(process.platform === 'win32' ? [PREVIEW_AGENT_BRIDGE_PORT] : []),
|
||||
]
|
||||
const ports = getPreviewListeningPorts()
|
||||
const pids = new Set<number>()
|
||||
|
||||
if (process.platform === 'win32') {
|
||||
@@ -367,11 +397,7 @@ function getUnixProcessGroupId(pid: number): number | null {
|
||||
}
|
||||
|
||||
async function assertPreviewPortsAvailable() {
|
||||
const ports = [
|
||||
PREVIEW_BACKEND_PORT,
|
||||
PREVIEW_FRONTEND_PORT,
|
||||
...(process.platform === 'win32' ? [PREVIEW_AGENT_BRIDGE_PORT] : []),
|
||||
]
|
||||
const ports = getPreviewListeningPorts()
|
||||
const checks = await Promise.all(ports.map(port => isPortAvailable(port)))
|
||||
const busy = ports.filter((_, index) => !checks[index])
|
||||
|
||||
@@ -964,6 +990,7 @@ export async function startPreview(ctx: any) {
|
||||
HERMES_WEB_UI_HOME: getPreviewHomeDir(),
|
||||
HERMES_WEBUI_STATE_DIR: getPreviewHomeDir(),
|
||||
HERMES_AGENT_BRIDGE_ENDPOINT: getPreviewAgentBridgeEndpoint(),
|
||||
HERMES_AGENT_BRIDGE_WORKER_PORT_BASE: String(PREVIEW_AGENT_BRIDGE_WORKER_PORT_BASE),
|
||||
AUTH_TOKEN: '',
|
||||
HERMES_WEB_UI_BACKEND_PORT: String(PREVIEW_BACKEND_PORT),
|
||||
HERMES_WEB_UI_FRONTEND_PORT: String(PREVIEW_FRONTEND_PORT),
|
||||
|
||||
@@ -30,6 +30,13 @@ Override with:
|
||||
HERMES_AGENT_BRIDGE_ENDPOINT=tcp://127.0.0.1:8765 python packages/server/src/services/hermes/agent-bridge/hermes_bridge.py
|
||||
```
|
||||
|
||||
Profile workers use the same platform defaults: TCP on Windows and IPC on
|
||||
macOS/Linux. Override worker transport with:
|
||||
|
||||
```bash
|
||||
HERMES_AGENT_BRIDGE_WORKER_TRANSPORT=tcp HERMES_AGENT_BRIDGE_WORKER_PORT_BASE=18780 python packages/server/src/services/hermes/agent-bridge/hermes_bridge.py
|
||||
```
|
||||
|
||||
The service discovers Hermes Agent in this order:
|
||||
|
||||
1. `--agent-root`
|
||||
|
||||
@@ -2416,7 +2416,9 @@ class WorkerProcess:
|
||||
def _worker_endpoint(key: str, namespace: str | None = None) -> str:
|
||||
namespace_key = f"{namespace or ''}\0{key}"
|
||||
safe = hashlib.sha256(namespace_key.encode("utf-8")).hexdigest()[:16]
|
||||
if os.name == "nt":
|
||||
transport = os.environ.get("HERMES_AGENT_BRIDGE_WORKER_TRANSPORT", "").strip().lower()
|
||||
use_tcp = transport == "tcp" or (transport not in {"ipc", "unix"} and os.name == "nt")
|
||||
if use_tcp:
|
||||
port_base = int(os.environ.get("HERMES_AGENT_BRIDGE_WORKER_PORT_BASE", "18780"))
|
||||
return f"tcp://127.0.0.1:{port_base + int(safe[:4], 16) % 1000}"
|
||||
root = Path(tempfile.gettempdir()) / "hermes-agent-bridge-workers"
|
||||
|
||||
Reference in New Issue
Block a user