Merge pull request #4088 from code-yeongyu/fix/session-agent-map-cleanup
fix(claude-code-session-state): clear session-agent map on delete and sync cleanup
This commit is contained in:
@@ -5063,6 +5063,27 @@ describe("BackgroundManager.handleEvent - session.deleted cascade", () => {
|
|||||||
|
|
||||||
manager.shutdown()
|
manager.shutdown()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("should clear session agent state for deleted sessions to prevent map leak", async () => {
|
||||||
|
//#given
|
||||||
|
const { setSessionAgent } = await import("../claude-code-session-state")
|
||||||
|
resetClaudeCodeSessionState()
|
||||||
|
const manager = createBackgroundManager()
|
||||||
|
const sessionID = "session-deleted-agent-leak"
|
||||||
|
setSessionAgent(sessionID, "sisyphus-junior")
|
||||||
|
expect(getSessionAgent(sessionID)).toBe("sisyphus-junior")
|
||||||
|
|
||||||
|
//#when
|
||||||
|
manager.handleEvent({
|
||||||
|
type: "session.deleted",
|
||||||
|
properties: { info: { id: sessionID } },
|
||||||
|
})
|
||||||
|
|
||||||
|
//#then
|
||||||
|
expect(getSessionAgent(sessionID)).toBeUndefined()
|
||||||
|
|
||||||
|
manager.shutdown()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("BackgroundManager.handleEvent - session.error", () => {
|
describe("BackgroundManager.handleEvent - session.error", () => {
|
||||||
|
|||||||
@@ -1660,6 +1660,7 @@ The fallback retry session is now created and can be inspected directly.
|
|||||||
|
|
||||||
if (tasksToCancel.size === 0) {
|
if (tasksToCancel.size === 0) {
|
||||||
this.clearTaskHistoryWhenParentTasksGone(sessionID)
|
this.clearTaskHistoryWhenParentTasksGone(sessionID)
|
||||||
|
clearSessionAgent(sessionID)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1698,6 +1699,7 @@ The fallback retry session is now created and can be inspected directly.
|
|||||||
|
|
||||||
this.rootDescendantCounts.delete(sessionID)
|
this.rootDescendantCounts.delete(sessionID)
|
||||||
clearDelegatedChildSessionBootstrap(sessionID)
|
clearDelegatedChildSessionBootstrap(sessionID)
|
||||||
|
clearSessionAgent(sessionID)
|
||||||
SessionCategoryRegistry.remove(sessionID)
|
SessionCategoryRegistry.remove(sessionID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -394,6 +394,8 @@ describe("executeSync", () => {
|
|||||||
expect(observed[0]?.bootstrap?.tools?.question).toBe(false)
|
expect(observed[0]?.bootstrap?.tools?.question).toBe(false)
|
||||||
expect(observed[0]?.bootstrap?.fallbackChain?.[0]?.model).toBe("gpt-5.4")
|
expect(observed[0]?.bootstrap?.fallbackChain?.[0]?.model).toBe("gpt-5.4")
|
||||||
expect(getDelegatedChildSessionBootstrap("ses-call-bootstrap")).toBeUndefined()
|
expect(getDelegatedChildSessionBootstrap("ses-call-bootstrap")).toBeUndefined()
|
||||||
|
// session-agent state for a sync session we created must be cleared after dispatch
|
||||||
|
expect(getSessionAgent("ses-call-bootstrap")).toBeUndefined()
|
||||||
} finally {
|
} finally {
|
||||||
clearAllDelegatedChildSessionBootstrap()
|
clearAllDelegatedChildSessionBootstrap()
|
||||||
clearSessionTools()
|
clearSessionTools()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { PluginInput } from "@opencode-ai/plugin"
|
import type { PluginInput } from "@opencode-ai/plugin"
|
||||||
import { setSessionAgent, subagentSessions, syncSubagentSessions } from "../../features/claude-code-session-state"
|
import { clearSessionAgent, setSessionAgent, subagentSessions, syncSubagentSessions } from "../../features/claude-code-session-state"
|
||||||
import { promptAsyncAfterSessionIdle } from "../../hooks/shared/prompt-async-gate"
|
import { promptAsyncAfterSessionIdle } from "../../hooks/shared/prompt-async-gate"
|
||||||
import { getAgentToolRestrictions, log } from "../../shared"
|
import { getAgentToolRestrictions, log } from "../../shared"
|
||||||
import { getAgentDisplayName, stripAgentListSortPrefix } from "../../shared/agent-display-names"
|
import { getAgentDisplayName, stripAgentListSortPrefix } from "../../shared/agent-display-names"
|
||||||
@@ -187,6 +187,7 @@ export async function executeSync(
|
|||||||
subagentSessions.delete(sessionID)
|
subagentSessions.delete(sessionID)
|
||||||
syncSubagentSessions.delete(sessionID)
|
syncSubagentSessions.delete(sessionID)
|
||||||
deleteSessionTools(sessionID)
|
deleteSessionTools(sessionID)
|
||||||
|
clearSessionAgent(sessionID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user