Skip to content

Commit 97b84ef

Browse files
authored
fix: properly recover from idle kill (#1758)
1 parent 02023b4 commit 97b84ef

4 files changed

Lines changed: 29 additions & 4 deletions

File tree

apps/code/src/renderer/features/sessions/hooks/useSessionConnection.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@ import { trpcClient } from "@renderer/trpc/client";
44
import type { Task } from "@shared/types";
55
import { getCloudUrlFromRegion } from "@shared/utils/urls";
66
import { useQueryClient } from "@tanstack/react-query";
7+
import { logger } from "@utils/logger";
78
import { useEffect } from "react";
89
import { getSessionService } from "../service/service";
9-
import type { AgentSession } from "../stores/sessionStore";
10+
import { type AgentSession, sessionStoreSetters } from "../stores/sessionStore";
1011
import { useChatTitleGenerator } from "./useChatTitleGenerator";
1112

13+
const log = logger.scope("session-connection");
14+
1215
const connectingTasks = new Set<string>();
1316
const activityRecorded = new Set<string>();
1417

@@ -112,6 +115,27 @@ export function useSessionConnection({
112115
if (isCloud) return;
113116
if (isSuspended) return;
114117

118+
if (session?.status === "error" && session?.idleKilled) {
119+
const taskRunId = session.taskRunId;
120+
connectingTasks.add(taskId);
121+
getSessionService()
122+
.clearSessionError(taskId, repoPath)
123+
.catch((error) => {
124+
log.error("Auto-reconnect after idle kill failed", error);
125+
sessionStoreSetters.updateSession(taskRunId, {
126+
idleKilled: false,
127+
errorMessage:
128+
"Session disconnected due to inactivity. Click Retry to reconnect.",
129+
});
130+
})
131+
.finally(() => {
132+
connectingTasks.delete(taskId);
133+
});
134+
return () => {
135+
connectingTasks.delete(taskId);
136+
};
137+
}
138+
115139
if (
116140
session?.status === "connected" ||
117141
session?.status === "connecting" ||

apps/code/src/renderer/features/sessions/hooks/useSessionViewState.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export function useSessionViewState(taskId: string, task: Task) {
1717
(!cloudStatus || cloudStatus === "queued" || cloudStatus === "in_progress");
1818
const isCloudRunTerminal = isCloud && !isCloudRunNotTerminal;
1919

20-
const hasError = session?.status === "error";
20+
const hasError = session?.status === "error" && !session?.idleKilled;
2121
const isRunning = isCloud ? !hasError : session?.status === "connected";
2222

2323
const events = session?.events ?? [];

apps/code/src/renderer/features/sessions/service/service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -585,11 +585,11 @@ export class SessionService {
585585
this.unsubscribeFromChannel(taskRunId);
586586
sessionStoreSetters.updateSession(taskRunId, {
587587
status: "error",
588-
errorMessage:
589-
"Session disconnected due to inactivity. Click Retry to reconnect.",
588+
errorMessage: "Session disconnected due to inactivity. Reconnecting…",
590589
isPromptPending: false,
591590
isCompacting: false,
592591
promptStartedAt: null,
592+
idleKilled: true,
593593
});
594594
}
595595

apps/code/src/renderer/features/sessions/stores/sessionStore.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ export interface AgentSession {
7878
contextSize?: number;
7979
/** Pre-computed conversation summary for commit/PR generation context */
8080
conversationSummary?: string;
81+
idleKilled?: boolean;
8182
}
8283

8384
// --- Config Option Helpers ---

0 commit comments

Comments
 (0)