Przeglądaj źródła

修复 Runner 协作模式能力握手被过滤的问题

Samien 1 miesiąc temu
rodzic
commit
a678e827a8
2 zmienionych plików z 13 dodań i 1 usunięć
  1. 1 1
      src/server/runnerHub.ts
  2. 12 0
      tests/server/runner.test.ts

+ 1 - 1
src/server/runnerHub.ts

@@ -246,7 +246,7 @@ export class RunnerHub {
         retired.add(previous.instance);this.retired.set(record.id,retired);this.disconnect(record.id);previous=undefined
       }
       if(match[2]!=='poll'&&ctx.get('x-runner-epoch')!==previous?.epoch)throw new HttpError(409,'执行连接代次已改变','runner_epoch_changed')
-      const state=this.online.get(record.id)??{instance,seen:Date.now(),features:[],epoch:`${this.epoch}:${randomUUID()}`};state.seen=Date.now();if(ctx.get('x-runner-features'))state.features=ctx.get('x-runner-features').split(',').filter(value=>['host-computer-tools-v1','idle-stop-policy-v1','computer-worker-v1','artifact-chunks-v1','helper-retirement-v1','computer-control-v1','shared-computer-v1','local-vm-v1','image-options-v1','image-ready-v1','compose-desktops-v1'].includes(value));this.online.set(record.id,state)
+      const state=this.online.get(record.id)??{instance,seen:Date.now(),features:[],epoch:`${this.epoch}:${randomUUID()}`};state.seen=Date.now();if(ctx.get('x-runner-features'))state.features=ctx.get('x-runner-features').split(',').filter(value=>['profile-computer-v1','host-computer-tools-v1','idle-stop-policy-v1','computer-worker-v1','artifact-chunks-v1','helper-retirement-v1','computer-control-v1','shared-computer-v1','local-vm-v1','image-options-v1','image-ready-v1','compose-desktops-v1'].includes(value));this.online.set(record.id,state)
       ctx.set('Cache-Control','no-store')
       if(match[2]==='poll') {
         if(ctx.method!=='GET')throw new HttpError(405,'仅允许 GET','method_not_allowed')

+ 12 - 0
tests/server/runner.test.ts

@@ -80,6 +80,18 @@ it('rejects Profile collaboration on a Runner that does not advertise the execut
  const id=randomUUID()
  expect(()=>hub.target('owner','local',{environmentId:id,agentId:id,ownerKey:'owner',hostAccess:true,profileSession:true})).toThrow('不支持本机协作模式')
 })
+it.each([false,true])('admits Profile collaboration after an actual computer Runner handshake (Compose: %s)',async compose=>{
+ controller.abort();await running
+ config.computers={runtime:'docker',imageId:'sha256:'+'0'.repeat(64),python:'/fixture/python',hermesSource:home,hermesHome:home,...(compose?{managedBy:'compose' as const}:{})}
+ runner=new RunnerAgent(config,home);controller=new AbortController();running=runner.run(controller.signal);void running.catch(()=>{})
+ await vi.waitFor(()=>expect((runner as any).serverEpoch).toBeTruthy())
+ const features=hub.summary(hub.records()[0]!).features
+ expect(features).toContain('profile-computer-v1')
+ expect(features).toEqual(expect.arrayContaining(['host-computer-tools-v1','computer-worker-v1','computer-control-v1']))
+ if(compose)expect(features).toContain('compose-desktops-v1')
+ const agent=store.createAgent('owner',{name:'协作握手',profile:'default',computer:'vm',execution:'computer',vmExecution:'profile'})
+ expect(()=>hub.target('owner','local',{agentId:agent.id,environmentId:agent.id,ownerKey:'owner',hostAccess:true,profileSession:true})).not.toThrow()
+})
 async function machine(path:string,body?:unknown,overrides:Record<string,string>={}){
   return fetch(`${config.serverURL}/api/runner/v1/${config.runnerId}/${path}`,{
     method:body===undefined?'GET':'POST',headers:{Authorization:`Bearer ${config.token}`,'x-runner-instance':runner.instance,'x-runner-protocol':'1','x-runner-epoch':(runner as any).serverEpoch,'Content-Type':'application/json',...overrides},...(body===undefined?{}:{body:JSON.stringify(body)})