fix(acp): reconnect agent when folder selector switches working directory

This commit is contained in:
xintaofei
2026-04-22 12:38:31 +08:00
parent d3d3a66263
commit 10922dd71a
2 changed files with 29 additions and 23 deletions

View File

@@ -110,6 +110,7 @@ export interface ConnectionState {
connectionId: string
contextKey: string
agentType: AgentType
workingDir: string | null
status: ConnectionStatus
promptCapabilities: PromptCapabilitiesInfo
supportsFork: boolean
@@ -134,6 +135,7 @@ type Action =
contextKey: string
connectionId: string
agentType: AgentType
workingDir: string | null
}
| { type: "CONNECTION_REMOVED"; contextKey: string }
| { type: "REMOVE_ALL" }
@@ -601,6 +603,7 @@ function connectionsReducer(
connectionId: action.connectionId,
contextKey: action.contextKey,
agentType: action.agentType,
workingDir: action.workingDir,
status: "connecting",
promptCapabilities: {
image: false,
@@ -2167,10 +2170,12 @@ export function AcpConnectionsProvider({ children }: { children: ReactNode }) {
throw createAlertedError(blocked.reason)
}
const nextWorkingDir = workingDir ?? null
const existing = storeRef.current.connections.get(contextKey)
if (existing) {
if (
existing.agentType === agentType &&
existing.workingDir === nextWorkingDir &&
existing.status !== "disconnected" &&
existing.status !== "error"
) {
@@ -2204,6 +2209,7 @@ export function AcpConnectionsProvider({ children }: { children: ReactNode }) {
contextKey,
connectionId,
agentType,
workingDir: nextWorkingDir,
})
const buffered = consumeBufferedEvents(connectionId)

View File

@@ -129,35 +129,35 @@ export function useConnectionLifecycle({
// Auto-connect when tab becomes active and workingDir is available.
// Depends on isActive + workingDir so that connections wait for folder
// info to load (workingDir transitions from undefined → folder.path).
// info to load (workingDir transitions from undefined → folder.path),
// and so that changing folders on an already-connected tab triggers a
// reconnect with the new cwd. The context's connect() dedups same-param
// calls and disconnects+reconnects when workingDir differs.
// Status changes must NOT re-trigger this to avoid infinite reconnect
// loops on transient errors.
useEffect(() => {
if (!isActive) return
if (!workingDir) return
let cancelled = false
const s = statusRef.current
if (!s || s === "disconnected" || s === "error") {
connConnectRef
.current(agentTypeRef.current, workingDir, sessionIdRef.current)
.then(() => {
if (!cancelled) {
setLastAutoConnectError(null)
}
})
.catch((e: unknown) => {
if (!cancelled) {
setLastAutoConnectError({
contextKey: contextKeyRef.current,
agentType: agentTypeRef.current,
message: normalizeErrorMessage(e),
})
}
if (!isExpectedConnectError(e)) {
console.error("[ConnLifecycle] auto-connect:", e)
}
})
}
connConnectRef
.current(agentTypeRef.current, workingDir, sessionIdRef.current)
.then(() => {
if (!cancelled) {
setLastAutoConnectError(null)
}
})
.catch((e: unknown) => {
if (!cancelled) {
setLastAutoConnectError({
contextKey: contextKeyRef.current,
agentType: agentTypeRef.current,
message: normalizeErrorMessage(e),
})
}
if (!isExpectedConnectError(e)) {
console.error("[ConnLifecycle] auto-connect:", e)
}
})
return () => {
cancelled = true
}