fix(web): agent check default model fallback; ensure browser session before desktop iframe (FIX-5)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
6aaf8c0704
commit
9244315768
4 files changed
+63
-22
No files matched your search
@@ -132,22 +132,29 @@ function DesktopView({
|
||||
});
|
||||
|
||||
// INT-3(VER-3b):桌面 iframe 直连 Selkies,不经过截图 / 操作接口,不会触发服务端的被动重连 →
|
||||
// 打开桌面时先调一次幂等的 reconnect(上游上下文还在时服务端什么都不做),失败再走自动重连
|
||||
// 打开桌面时先调一次幂等的 reconnect(上游上下文还在时服务端什么都不做),失败再走自动重连。
|
||||
// FIX-5(VER-4):先等这次确认结束再连桌面画面,不再先连上黑屏、等 5 秒黑屏检测才重连
|
||||
const ensure = useBrowserReconnect(site.id);
|
||||
const { mutate: ensureMutate } = ensure;
|
||||
const sid = s && s.controller !== "closed" ? s.id : null;
|
||||
const ensured = useRef<string | null>(null);
|
||||
const [ensuredSid, setEnsuredSid] = useState<string | null>(null);
|
||||
useEffect(() => {
|
||||
if (!sid || ensured.current === sid) return;
|
||||
ensured.current = sid;
|
||||
ensureMutate(sid, { onError: () => setStuck(true) });
|
||||
ensureMutate(sid, {
|
||||
onError: () => setStuck(true),
|
||||
onSettled: () => setEnsuredSid(sid),
|
||||
});
|
||||
}, [sid, ensureMutate]);
|
||||
/** 会话已确认(或已关闭):可以连桌面画面 */
|
||||
const ready = !sid || ensuredSid === sid;
|
||||
|
||||
// 画面加载失败或黑屏超过 5 秒:每个会话自动重连一次(之后靠「重新连接」按钮)
|
||||
const blankTried = useRef<string | null>(null);
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: reloadKey 变化 = 新一轮加载,重新计时
|
||||
useEffect(() => {
|
||||
if (!sid || blankTried.current === sid) return;
|
||||
if (!sid || !ready || blankTried.current === sid) return;
|
||||
const t = setTimeout(() => {
|
||||
if (loaded && !desktopBlank(frame.current)) return;
|
||||
blankTried.current = sid;
|
||||
@@ -155,7 +162,7 @@ function DesktopView({
|
||||
setStuck(true);
|
||||
}, BLANK_TIMEOUT_MS);
|
||||
return () => clearTimeout(t);
|
||||
}, [sid, loaded, reloadKey]);
|
||||
}, [sid, ready, loaded, reloadKey]);
|
||||
// 别处(Agent 操作、截图)触发的重连成功后也重建桌面连接
|
||||
const reconnectedAt = s?.reconnect?.status === "ok" ? s.reconnect.at : null;
|
||||
const prevReconnect = useRef(reconnectedAt);
|
||||
@@ -187,8 +194,9 @@ function DesktopView({
|
||||
const waiting = waitingText(s.waitingReason);
|
||||
const cred = credentialBadge(s.credential);
|
||||
const leaseHolder = s.lease ? holderName(s.lease.holder) : null;
|
||||
const conn: { tone: StatusTone; text: string } =
|
||||
rc.state.phase === "reconnecting"
|
||||
const conn: { tone: StatusTone; text: string } = !ready
|
||||
? { tone: "neutral", text: "正在确认浏览器会话" }
|
||||
: rc.state.phase === "reconnecting"
|
||||
? { tone: "warning", text: "正在重新连接" }
|
||||
: rc.state.phase === "failed"
|
||||
? { tone: "destructive", text: "连接中断" }
|
||||
@@ -278,15 +286,27 @@ function DesktopView({
|
||||
<ReconnectPanel state={rc.state} onRetry={rc.retry} />
|
||||
</div>
|
||||
) : null}
|
||||
<iframe
|
||||
key={reloadKey}
|
||||
ref={frame}
|
||||
title="浏览器桌面"
|
||||
src={status.path}
|
||||
onLoad={() => setLoaded(true)}
|
||||
allow="clipboard-read; clipboard-write; fullscreen; keyboard-map"
|
||||
className="block aspect-[1280/900] w-full border-0 bg-scrim"
|
||||
/>
|
||||
{ready ? (
|
||||
<iframe
|
||||
key={reloadKey}
|
||||
ref={frame}
|
||||
title="浏览器桌面"
|
||||
src={status.path}
|
||||
onLoad={() => setLoaded(true)}
|
||||
allow="clipboard-read; clipboard-write; fullscreen; keyboard-map"
|
||||
className="block aspect-[1280/900] w-full border-0 bg-scrim"
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
role="status"
|
||||
className="grid aspect-[1280/900] w-full place-items-center bg-scrim text-caption text-muted-foreground"
|
||||
>
|
||||
<span className="flex items-center gap-2">
|
||||
<LoaderCircle className="h-4 w-4 animate-spin" />
|
||||
正在确认浏览器会话…
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user