|
|
@@ -18,12 +18,20 @@ const cloudSelected=computed(()=>agent.value?.computer==='cloud'||(agent.value?.
|
|
|
const computerChoice=computed(()=>state.value?.fixedCapacity&&agent.value?.execution==='computer'?(state.value.desktopId??'off'):agent.value?.computer??(state.value?.enabled?'vm':'off'))
|
|
|
const canAllowHost=computed(()=>!!agent.value&&supportsHostEnvironment(agent.value))
|
|
|
const localVmSelected=computed(()=>canAllowHost.value&&!cloudSelected.value)
|
|
|
+const desktopHosts=computed(()=>native.value?.hosts??[])
|
|
|
+const hostSelectable=computed(()=>desktopHosts.value.some(host=>host.id!=='local'))
|
|
|
+const boundHost=computed(()=>agent.value?.desktopHost||'')
|
|
|
+function chooseDesktopHost(value:string){
|
|
|
+ if(computerChoiceDisabled.value||!nativeSelected.value||value===boundHost.value)return
|
|
|
+ void run(()=>apiRequest(`/api/app/agents/${selected.value}/computer-selection`,{method:'PUT',body:{computer:nativeSelected.value as string,desktopHost:value||null}}))
|
|
|
+}
|
|
|
+const authorizeBody=():Record<string,string>=>boundHost.value?{hostId:boundHost.value}:{}
|
|
|
const computerChoices=computed(()=>[
|
|
|
{value:'auto',label:'自动',description:'按可用环境自动选择',icon:'bolt' as const,disabled:false},
|
|
|
{value:'cloud',label:'云端 · Grok Bot',description:'共享云端电脑,持续保存工作',icon:'globe' as const,disabled:false},
|
|
|
...(state.value?.fixedCapacity?(state.value.desktops??[]).map(desktop=>({value:desktop.id,label:desktop.name,description:(desktop.imageKey==='cursor'?'Cursor Universal · ':'标准桌面 · ')+(desktop.ready?'已就绪':'尚未就绪'),icon:'monitor' as const,disabled:desktop.available===false})):[{value:'vm',label:'本地虚拟机',description:'在隔离的本地桌面中工作',icon:'monitor' as const,disabled:false}]),
|
|
|
- {value:'local',label:'本机',description:native.value?.host?.name??'请在电脑上打开夭夭桌面端',icon:'monitor' as const,disabled:!native.value?.local.supported},
|
|
|
- {value:'browser',label:'仅浏览器',description:native.value?.browser.available?'独立浏览器,保存登录资料':'请在电脑上打开夭夭桌面端',icon:'globe' as const,disabled:!native.value?.browser.available},
|
|
|
+ {value:'local',label:'本机',description:native.value?.host?.name??'请在电脑上打开夭夭桌面端',icon:'monitor' as const,disabled:!desktopHosts.value.some(host=>host.local.supported)},
|
|
|
+ {value:'browser',label:'仅浏览器',description:native.value?.browser.available?'独立浏览器,保存登录资料':'请在电脑上打开夭夭桌面端',icon:'globe' as const,disabled:!desktopHosts.value.some(host=>host.browser.available)},
|
|
|
{value:'off',label:'不使用电脑',description:'使用基础机器人的其他工具',icon:'stop' as const,disabled:false},
|
|
|
])
|
|
|
const computerChoiceDisabled=computed(()=>loading.value||!state.value||busy.value||state.value.inUse||!!agent.value?.remoteAgentId||!!agent.value?.temporaryGoalId)
|
|
|
@@ -125,13 +133,20 @@ onBeforeUnmount(()=>{closed=true;revision++;clearTimeout(timer)})
|
|
|
<template v-if="canAllowHost&&agent.allowHostEnvironment">
|
|
|
<p class="hint">允许 Bot 同时使用 Hermes 所在电脑的文件和命令。{{cloudSelected?'云端虚拟机仍使用独立的云端工具和文件。':'虚拟机工具仍在隔离 Linux 桌面内执行。'}}上方显示虚拟机画面。</p>
|
|
|
<p v-if="native?.local.ready" class="hint">已连接 {{native.host?.name}},Bot 也可操作本机桌面。</p>
|
|
|
- <button v-else-if="native?.local.supported" :disabled="busy||!isAdmin" @click="run(()=>apiRequest(`/api/app/agents/${selected}/desktop-environment/authorize`,{method:'POST',body:{},timeoutMs:125000}))">授权本机桌面操作</button>
|
|
|
+ <button v-else-if="native?.local.supported" :disabled="busy||!isAdmin" @click="run(()=>apiRequest(`/api/app/agents/${selected}/desktop-environment/authorize`,{method:'POST',body:authorizeBody(),timeoutMs:125000}))">授权本机桌面操作</button>
|
|
|
</template>
|
|
|
<template v-if="nativeSelected">
|
|
|
<p>{{nativeSelected==='local'?'机器人将查看并操作已连接电脑的真实桌面。':'浏览器在已连接的桌面端运行,机器人和你使用同一组标签页。'}}连接电脑:{{native?.host?.name??'未连接'}}。</p>
|
|
|
+ <label v-if="hostSelectable" class="desktop-host-option">操作的电脑
|
|
|
+ <select aria-label="操作的电脑" :value="boundHost" :disabled="busy" @change="chooseDesktopHost(($event.target as HTMLSelectElement).value)">
|
|
|
+ <option value="">自动选择</option>
|
|
|
+ <option v-for="host in desktopHosts" :key="host.id" :value="host.id">{{host.id==='local'?'本机':host.name||'桌面主机'}}{{host.online?'':' · 离线'}}</option>
|
|
|
+ </select>
|
|
|
+ <span class="hint">选择机器人在哪台电脑上查看和操作;每台电脑需单独授权。</span>
|
|
|
+ </label>
|
|
|
<template v-if="nativeSelected==='local'">
|
|
|
<div class="permission-list"><span>{{native?.local.authorized?'✓':'○'}} 本机控制授权</span><span>{{native?.local.screen?'✓':'○'}} 屏幕录制</span><span>{{native?.local.accessibility?'✓':'○'}} 辅助功能</span></div>
|
|
|
- <button v-if="!native?.local.ready" class="primary" :disabled="busy||!native?.online||!isAdmin" @click="run(()=>apiRequest(`/api/app/agents/${selected}/desktop-environment/authorize`,{method:'POST',body:{},timeoutMs:125000}))">在桌面端授权</button>
|
|
|
+ <button v-if="!native?.local.ready" class="primary" :disabled="busy||!native?.online||!isAdmin" @click="run(()=>apiRequest(`/api/app/agents/${selected}/desktop-environment/authorize`,{method:'POST',body:authorizeBody(),timeoutMs:125000}))">在桌面端授权</button>
|
|
|
<p v-if="!native?.local.ready" class="hint">在连接的 Mac 上确认授权,并按系统提示开启权限;系统可能要求重新打开 App。</p>
|
|
|
</template>
|
|
|
<label v-else>浏览器资料<select :value="native?.browser.profile" :disabled="busy" @change="run(()=>apiRequest(`/api/app/agents/${selected}/browser-profile`,{method:'PUT',body:{profile:($event.target as HTMLSelectElement).value}}))"><option value="persistent">此机器人的浏览器 · 保存登录</option><option value="temporary">临时浏览器 · 退出桌面端后清除</option></select></label>
|