welcome agent 处理优化

This commit is contained in:
xintaofei
2026-03-07 21:41:25 +08:00
parent 62d8e1a0b0
commit b7058a2bb6
2 changed files with 71 additions and 19 deletions

View File

@@ -1,6 +1,6 @@
"use client" "use client"
import { useEffect, useState } from "react" import { useEffect, useRef, useState } from "react"
import { useTranslations } from "next-intl" import { useTranslations } from "next-intl"
import { acpListAgents } from "@/lib/tauri" import { acpListAgents } from "@/lib/tauri"
import type { AgentType, AcpAgentInfo } from "@/lib/types" import type { AgentType, AcpAgentInfo } from "@/lib/types"
@@ -30,6 +30,16 @@ export function AgentSelector({
const [selected, setSelected] = useState<AgentType | null>( const [selected, setSelected] = useState<AgentType | null>(
defaultAgentType ?? null defaultAgentType ?? null
) )
const onSelectRef = useRef(onSelect)
const onAgentsLoadedRef = useRef(onAgentsLoaded)
useEffect(() => {
onSelectRef.current = onSelect
}, [onSelect])
useEffect(() => {
onAgentsLoadedRef.current = onAgentsLoaded
}, [onAgentsLoaded])
useEffect(() => { useEffect(() => {
let cancelled = false let cancelled = false
@@ -46,7 +56,7 @@ export function AgentSelector({
) )
const visible = sorted.filter((a) => a.enabled) const visible = sorted.filter((a) => a.enabled)
setAgents(visible) setAgents(visible)
onAgentsLoaded?.(visible) onAgentsLoadedRef.current?.(visible)
if (defaultAgentType) { if (defaultAgentType) {
const found = visible.find( const found = visible.find(
(a) => a.agent_type === defaultAgentType && a.available (a) => a.agent_type === defaultAgentType && a.available
@@ -57,20 +67,20 @@ export function AgentSelector({
const first = visible.find((a) => a.available) const first = visible.find((a) => a.available)
if (first) { if (first) {
setSelected(first.agent_type) setSelected(first.agent_type)
onSelect(first.agent_type) onSelectRef.current(first.agent_type)
} }
} }
} else { } else {
const first = visible.find((a) => a.available) const first = visible.find((a) => a.available)
if (first) { if (first) {
setSelected(first.agent_type) setSelected(first.agent_type)
onSelect(first.agent_type) onSelectRef.current(first.agent_type)
} }
} }
} catch { } catch {
if (!cancelled && requestId === latestRequestId) { if (!cancelled && requestId === latestRequestId) {
setAgents([]) setAgents([])
onAgentsLoaded?.([]) onAgentsLoadedRef.current?.([])
} }
} }
} }
@@ -106,7 +116,7 @@ export function AgentSelector({
unlisten() unlisten()
} }
} }
}, [defaultAgentType, onAgentsLoaded, onSelect]) }, [defaultAgentType])
const handleSelect = (agentType: AgentType) => { const handleSelect = (agentType: AgentType) => {
setSelected(agentType) setSelected(agentType)

View File

@@ -301,6 +301,8 @@ export function WelcomeInputPanel({
disconnect: connDisconnect, disconnect: connDisconnect,
sessionId: connSessionId, sessionId: connSessionId,
} = conn } = conn
const isConnecting =
connStatus === "connecting" || connStatus === "downloading"
const connectionModes = useMemo( const connectionModes = useMemo(
() => conn.modes?.available_modes ?? [], () => conn.modes?.available_modes ?? [],
[conn.modes?.available_modes] [conn.modes?.available_modes]
@@ -326,11 +328,38 @@ export function WelcomeInputPanel({
const externalIdSavedRef = useRef(false) const externalIdSavedRef = useRef(false)
const sessionIdRef = useRef<string | null>(null) const sessionIdRef = useRef<string | null>(null)
const refreshingCurrentAgentRef = useRef(false) const refreshingCurrentAgentRef = useRef(false)
const agentStatusRefreshTimerRef = useRef<ReturnType<
typeof setTimeout
> | null>(null)
const phaseRef = useRef(phase)
const workingDirRef = useRef(workingDir)
const connStatusRef = useRef(connStatus)
const isConnectingRef = useRef(false)
const connConnectRef = useRef(connConnect)
const connDisconnectRef = useRef(connDisconnect)
useEffect(() => { useEffect(() => {
if (connSessionId) { if (connSessionId) {
sessionIdRef.current = connSessionId sessionIdRef.current = connSessionId
} }
}, [connSessionId]) }, [connSessionId])
useEffect(() => {
phaseRef.current = phase
}, [phase])
useEffect(() => {
workingDirRef.current = workingDir
}, [workingDir])
useEffect(() => {
connStatusRef.current = connStatus
}, [connStatus])
useEffect(() => {
isConnectingRef.current = isConnecting
}, [isConnecting])
useEffect(() => {
connConnectRef.current = connConnect
}, [connConnect])
useEffect(() => {
connDisconnectRef.current = connDisconnect
}, [connDisconnect])
const trySaveExternalId = useCallback(() => { const trySaveExternalId = useCallback(() => {
if ( if (
@@ -353,29 +382,33 @@ export function WelcomeInputPanel({
if (connSessionId) trySaveExternalId() if (connSessionId) trySaveExternalId()
}, [connSessionId, trySaveExternalId]) }, [connSessionId, trySaveExternalId])
const isConnecting =
connStatus === "connecting" || connStatus === "downloading"
useEffect(() => { useEffect(() => {
let cancelled = false let cancelled = false
let unlisten: (() => void) | null = null let unlisten: (() => void) | null = null
const syncCurrentAgentStatus = async () => { const syncCurrentAgentStatus = async () => {
if (cancelled) return if (cancelled) return
if (phase !== "welcome") return if (phaseRef.current !== "welcome") return
if (!workingDir) return const currentWorkingDir = workingDirRef.current
if (!currentWorkingDir) return
if (refreshingCurrentAgentRef.current) return if (refreshingCurrentAgentRef.current) return
if (connStatus === "prompting" || isConnecting) return const currentConnStatus = connStatusRef.current
if (currentConnStatus === "prompting" || isConnectingRef.current) return
refreshingCurrentAgentRef.current = true refreshingCurrentAgentRef.current = true
try { try {
setAgentConnectError(null) setAgentConnectError(null)
if (connStatus === "connected") { if (currentConnStatus === "connected") {
await connDisconnect() await connDisconnectRef.current()
} }
await connConnect(selectedAgentRef.current, workingDir, undefined, { await connConnectRef.current(
source: "auto_link", selectedAgentRef.current,
}) currentWorkingDir,
undefined,
{
source: "auto_link",
}
)
if (!cancelled) { if (!cancelled) {
setAgentConnectError(null) setAgentConnectError(null)
} }
@@ -403,7 +436,12 @@ export function WelcomeInputPanel({
) { ) {
return return
} }
void syncCurrentAgentStatus() if (agentStatusRefreshTimerRef.current) {
clearTimeout(agentStatusRefreshTimerRef.current)
}
agentStatusRefreshTimerRef.current = setTimeout(() => {
void syncCurrentAgentStatus()
}, 120)
}) })
) )
.then((dispose) => { .then((dispose) => {
@@ -419,11 +457,15 @@ export function WelcomeInputPanel({
return () => { return () => {
cancelled = true cancelled = true
if (agentStatusRefreshTimerRef.current) {
clearTimeout(agentStatusRefreshTimerRef.current)
agentStatusRefreshTimerRef.current = null
}
if (unlisten) { if (unlisten) {
unlisten() unlisten()
} }
} }
}, [connConnect, connDisconnect, connStatus, isConnecting, phase, workingDir]) }, [])
const prevStatusRef = useRef(connStatus) const prevStatusRef = useRef(connStatus)