|
|
@@ -1996,6 +1996,51 @@ it('applies Bot settings to the live agent after a cold resume restores its pers
|
|
|
expect(requests.filter(r => r.method === 'session.resume')).toHaveLength(2)
|
|
|
})
|
|
|
|
|
|
+it.each([
|
|
|
+ { hostname:'127.0.0.1', reported:true },
|
|
|
+ { hostname:'localhost', reported:true },
|
|
|
+ { hostname:'127.0.0.1', reported:false },
|
|
|
+ { hostname:'localhost', reported:false },
|
|
|
+])('keeps Hermes connected across client startup and shutdown at $hostname (metadata=$reported)', async ({hostname,reported}) => {
|
|
|
+ const bot=agent('独立服务器'),c=direct(bot.id),target=nodes.target(owner,'local')
|
|
|
+ target.url=new URL(`http://${hostname}:${target.url.port}`)
|
|
|
+ const original=target.session.request.bind(target.session)
|
|
|
+ const metadata={version:1,profile:'default',platform:'linux',osRelease:'6.8',arch:'x86_64',nativeTools:{terminal:['terminal'],files:['read_file','write_file'],desktop:['computer_use'],browser:['browser_navigate']}}
|
|
|
+ vi.spyOn(target.session,'request').mockImplementation(async(path,options)=>path.startsWith('/api/plugins/yaoyao-bot-bridge/')
|
|
|
+ ? {status:200,headers:new Headers(),body:Buffer.from(JSON.stringify({ok:true,version:1,ready:true,native_tools:true,in_process:true,...(reported?{runtime_environment:metadata}:{})}))}
|
|
|
+ : original(path,options))
|
|
|
+ configuredCwds.set('default','/hermes/project')
|
|
|
+ saveHostTools(home,{vm:false,cloud:false})
|
|
|
+ const desktop=new DesktopEnvironments(store,{pushAuthorizationVersion:()=>0} as any,{localNodeID:'fixture',requireSource:()=>{}} as any)
|
|
|
+ runtime.desktopEnvironments=desktop
|
|
|
+ const record=vi.fn();runtime.inspector={record} as any
|
|
|
+ const clientId=randomUUID()
|
|
|
+ try {
|
|
|
+ await finished(runtime.send(owner,c.id,{requestId:randomUUID(),content:'检查服务端目录',deviceHost:null}).id)
|
|
|
+ desktop.remoteExchange(clientId,{host:{id:randomUUID(),name:'服务器',platform:'darwin',screen:false,accessibility:false,approved:[]},results:[]})
|
|
|
+ await finished(runtime.send(owner,c.id,{requestId:randomUUID(),content:'检查服务端目录',deviceHost:clientId}).id)
|
|
|
+ desktop.dropHost(clientId)
|
|
|
+ await finished(runtime.send(owner,c.id,{requestId:randomUUID(),content:'检查服务端目录',deviceHost:clientId}).id)
|
|
|
+ const snapshots=record.mock.calls.map(([, ,entry])=>entry).filter(entry=>entry.method==='bot.environment').map(entry=>entry.data.snapshot)
|
|
|
+ expect(snapshots).toHaveLength(3)
|
|
|
+ expect(snapshots.every(snapshot=>snapshot.runtime.connected&&snapshot.cwd==='/hermes/project')).toBe(true)
|
|
|
+ expect(snapshots.map(snapshot=>snapshot.runtime.metadata)).toEqual(reported?[metadata,metadata,metadata]:[undefined,undefined,undefined])
|
|
|
+ expect(snapshots[0].desktop.hosts).toEqual([])
|
|
|
+ expect(snapshots[1].desktop.hosts[0]).toMatchObject({id:clientId,kind:'computer',platform:'darwin',online:true})
|
|
|
+ expect(snapshots[2].desktop.hosts[0]).toMatchObject({id:clientId,kind:'computer',online:false})
|
|
|
+ const prompts=requests.filter(request=>request.method==='prompt.submit').map(request=>String(request.params.text))
|
|
|
+ expect(prompts).toHaveLength(3)
|
|
|
+ for(const prompt of prompts){
|
|
|
+ expect(prompt).toContain('服务端 Hermes 已连接')
|
|
|
+ expect(prompt).toContain('操作服务端运行环境时优先使用')
|
|
|
+ expect(prompt).toContain('Hermes 本轮工作目录(已确认):"/hermes/project"')
|
|
|
+ expect(prompt).toContain(reported?'"desktop":["computer_use"]':'原生能力与系统信息尚未由工具桥上报')
|
|
|
+ }
|
|
|
+ expect(prompts[1]).toContain(`host="${clientId}"`)
|
|
|
+ expect(prompts[2]).toContain('当前离线或未连接')
|
|
|
+ } finally {desktop.close()}
|
|
|
+})
|
|
|
+
|
|
|
it('submits capability-based Bot context with current origins, confirmed cwd and no keyword-selected environment', async () => {
|
|
|
const bot = agent('环境助手'), c = direct(bot.id), target = nodes.target(owner, 'local')
|
|
|
const originalRequest = target.session.request.bind(target.session)
|