welcome agent 处理优化
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user