fix bridge first-turn disconnect during Hermes bootstrap

This commit is contained in:
Jack
2026-10-22 15:28:44 +08:00
parent 99e5687ce0
commit ce76dffa84
3 changed files with 68 additions and 1 deletions
+30
View File
@@ -1,3 +1,4 @@
import { execFileSync } from 'child_process'
import { EventEmitter } from 'events'
import { chmodSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'fs'
import { createServer, type Server } from 'net'
@@ -113,6 +114,35 @@ describe('agent bridge manager command resolution', () => {
})
})
it('bootstraps before the bridge starts even when bootstrap replaces the interpreter', async () => {
const root = join(tempDir, 'agent root')
const script = join(tempDir, 'bridge.py')
mkdirSync(root, { recursive: true })
writeFileSync(join(root, 'hermes_bootstrap.py'), [
'import os, sys',
"if os.environ.get('TEST_BRIDGE_BOOTSTRAPPED') != 'yes':",
" os.environ['TEST_BRIDGE_BOOTSTRAPPED'] = 'yes'",
' os.execv(sys.executable, [sys.executable, *sys.orig_argv[1:]])',
].join('\n'))
writeFileSync(script, [
'import json, os, sys',
"assert os.environ.get('TEST_BRIDGE_BOOTSTRAPPED') == 'yes'",
'print(json.dumps(sys.argv))',
].join('\n'))
const { buildAgentBridgeLaunchArgs } = await import('../../packages/server/src/services/hermes/agent-bridge/manager')
const args = buildAgentBridgeLaunchArgs({ command: 'python3', argsPrefix: [], agentRoot: root, hermesHome: tempDir }, script)
const env = { ...process.env }
delete env.TEST_BRIDGE_BOOTSTRAPPED
const output = execFileSync(process.platform === 'win32' ? 'python' : 'python3', [...args, '--endpoint', 'ipc:///test.sock'], { env, encoding: 'utf8', timeout: 10000 })
expect(JSON.parse(output.trim())).toEqual([script, '--endpoint', 'ipc:///test.sock'])
})
it('preserves legacy launch arguments when Hermes has no bootstrap module', async () => {
const { buildAgentBridgeLaunchArgs } = await import('../../packages/server/src/services/hermes/agent-bridge/manager')
expect(buildAgentBridgeLaunchArgs({ command: 'uv', argsPrefix: ['run', 'python'], agentRoot: tempDir, hermesHome: tempDir }, 'bridge.py'))
.toEqual(['run', 'python', 'bridge.py'])
})
it('injects Web UI OpenRouter attribution into the bridge process env by default', async () => {
const { buildAgentBridgeProcessEnv } = await import('../../packages/server/src/services/hermes/agent-bridge/manager')
const env = buildAgentBridgeProcessEnv('ipc:///tmp/test.sock', '/tmp/hermes-home', '/tmp/hermes-agent')