|
|
@@ -11,7 +11,7 @@ import type {LocalAuthStore} from './localAuth.js'
|
|
|
import type {WorkspaceNodes,GatewayTarget} from './workspaceGateway.js'
|
|
|
import {requireTeamToolBridge} from './workspaceToolLease.js'
|
|
|
import type {SharedComputers} from './sharedComputers.js'
|
|
|
-import type {WorkspaceAgent} from '../shared/workspace.js'
|
|
|
+import {agentEnvs,deriveComputer,type WorkspaceAgent} from '../shared/workspace.js'
|
|
|
import type {ComputerControlStatus,ComputerFrame} from '../shared/computerControl.js'
|
|
|
|
|
|
interface Descriptor {gatewayUrl:string;gatewayToken:string;networkToken:string;execDaemonUrl:string;execDaemonAuthToken:string}
|
|
|
@@ -187,15 +187,24 @@ export class GrokCloud {
|
|
|
if(!token)throw new HttpError(400,'请先通过浏览器完成 Grok Bot 授权。','grok_login_missing');ctx.body=await this.configure(owner,token,body.version,refreshToken)
|
|
|
})
|
|
|
router.put('/api/app/agents/:id/computer-selection',async ctx=>{
|
|
|
- const owner=this.auth.require(ctx).id,agent=this.agent(owner,ctx.params.id),body=parse(z.object({computer:z.enum(['auto','cloud','vm','local','browser','off']),desktopHost:z.union([z.literal('local'),z.string().uuid(),z.null()]).optional(),allowHostEnvironment:z.boolean().optional(),vmExecution:z.enum(['worker','profile']).optional()}).strict(),(ctx.request as any).body)
|
|
|
+ const owner=this.auth.require(ctx).id,agent=this.agent(owner,ctx.params.id),body=parse(z.union([
|
|
|
+ z.object({envs:z.object({vm:z.boolean().optional(),cloud:z.boolean().optional(),desktop:z.boolean().optional(),browser:z.boolean().optional()}).strict(),desktopHost:z.union([z.literal('local'),z.string().uuid(),z.null()]).optional()}).strict(),
|
|
|
+ z.object({computer:z.enum(['auto','cloud','vm','local','browser','off']),desktopHost:z.union([z.literal('local'),z.string().uuid(),z.null()]).optional(),allowHostEnvironment:z.boolean().optional(),vmExecution:z.enum(['worker','profile']).optional()}).strict(),
|
|
|
+ ]),(ctx.request as any).body)
|
|
|
+ const legacy='computer' in body
|
|
|
+ const legacyBody=legacy?body:undefined
|
|
|
+ const envsBody=legacy?undefined:body.envs
|
|
|
+ const current=agentEnvs(agent)
|
|
|
+ const next=envsBody?{vm:envsBody.vm===true,cloud:envsBody.cloud===true,desktop:envsBody.desktop===true,browser:envsBody.browser===true}:undefined
|
|
|
+ const targetComputer=next?deriveComputer(next):legacyBody!.computer
|
|
|
this.beforeSelection?.(owner,agent.id);this.shared.assertLocalVmIdle(owner,[agent.id]);if(this.current(owner))throw new HttpError(409,'请先交还云端电脑','computer_busy')
|
|
|
- if(body.vmExecution==='profile'&&body.allowHostEnvironment===false)throw new HttpError(400,'本机协作模式需要本机环境,请选择虚拟机模式','computer_profile_host_required')
|
|
|
- const vmExecution=body.computer==='vm'?(body.vmExecution??(body.allowHostEnvironment===false?'worker':agent.vmExecution)??'worker'):'worker'
|
|
|
- const allowHostEnvironment=(body.computer==='vm'&&vmExecution==='profile')||(['vm','cloud'].includes(body.computer)&&(body.allowHostEnvironment??(body.vmExecution==='worker'?false:agent.allowHostEnvironment)??false))
|
|
|
- if(body.computer==='vm'&&allowHostEnvironment)this.nodes.targetForAgent(owner,{...agent,execution:'computer',computer:'vm',allowHostEnvironment:true,vmExecution})
|
|
|
- const enteringCloud=body.computer==='cloud'&&agent.computer!=='cloud'
|
|
|
+ if(legacyBody&&legacyBody.vmExecution==='profile'&&legacyBody.allowHostEnvironment===false)throw new HttpError(400,'本机协作模式需要本机环境,请选择虚拟机模式','computer_profile_host_required')
|
|
|
+ const vmExecution=targetComputer==='vm'?(next?(agent.vmExecution??'worker'):(legacyBody!.vmExecution??(legacyBody!.allowHostEnvironment===false?'worker':agent.vmExecution)??'worker')):'worker'
|
|
|
+ const allowHostEnvironment=next?false:((legacyBody!.computer==='vm'&&vmExecution==='profile')||(['vm','cloud'].includes(legacyBody!.computer)&&(legacyBody!.allowHostEnvironment??(legacyBody!.vmExecution==='worker'?false:agent.allowHostEnvironment)??false)))
|
|
|
+ if(legacyBody&&legacyBody.computer==='vm'&&allowHostEnvironment)this.nodes.targetForAgent(owner,{...agent,execution:'computer',computer:'vm',allowHostEnvironment:true,vmExecution})
|
|
|
+ const enteringCloud=(next?next.cloud:legacyBody!.computer==='cloud')&&!current.cloud
|
|
|
if(enteringCloud)await this.requireAvailable(owner,agent,this.nodes.target(owner,agent.nodeId))
|
|
|
- this.store.atomic(()=>{const execution=body.computer==='vm'?'computer':body.computer==='auto'?(agent.execution??'profile'):'profile';if(execution!=='computer'&&agent.computerEnvironmentId)this.shared.detachLocalVm(owner,agent);this.store.updateAgent(owner,agent.id,{computer:body.computer,execution,allowHostEnvironment,vmExecution,...(body.desktopHost!==undefined?{desktopHost:body.desktopHost}:{})});const current=this.store.require<WorkspaceAgent>(owner,'agent',agent.id);this.store.prepareAgent?.(owner,current);this.store.put(owner,'agent',agent.id,current)})
|
|
|
+ this.store.atomic(()=>{const execution=targetComputer==='vm'?'computer':targetComputer==='auto'?(agent.execution??'profile'):'profile';if(execution!=='computer'&&agent.computerEnvironmentId)this.shared.detachLocalVm(owner,agent);this.store.updateAgent(owner,agent.id,{...(next?{envs:next}:{computer:legacyBody!.computer}),...(body.desktopHost!==undefined?{desktopHost:body.desktopHost}:{}),execution,allowHostEnvironment,vmExecution});const updated=this.store.require<WorkspaceAgent>(owner,'agent',agent.id);this.store.prepareAgent?.(owner,updated);this.store.put(owner,'agent',agent.id,updated)})
|
|
|
if(enteringCloud)await this.connect(owner)
|
|
|
ctx.body={agent:this.store.agentSummary(this.store.require<WorkspaceAgent>(owner,'agent',agent.id))}
|
|
|
})
|