fix(acp): reconnect agent when folder selector switches working directory
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user