fix(session-recovery): preflight idle recovery fanout

This commit is contained in:
YeonGyu-Kim
2026-05-17 16:17:36 +09:00
parent 1fea761cf2
commit 55312cc4b6
4 changed files with 200 additions and 20 deletions
+52
View File
@@ -210,4 +210,56 @@ describe("session-recovery hook interrupted idle recovery", () => {
// then
expect(result).toBe(false)
})
test("#given a newer user turn follows an unfinished assistant turn #when idle recovery runs #then it does not recover the stale assistant", async () => {
// given
const promptAsyncCalls: PromptAsyncCall[] = []
const ctx = {
client: {
session: {
messages: async () => ({
data: [
{
info: {
id: "msg_stale_assistant",
role: "assistant",
sessionID: "ses_stale_after_user",
finish: "tool-calls",
},
parts: [
{
type: "tool_use",
id: "toolu_stale_pending",
name: "bash",
input: {},
state: { status: "pending" },
},
],
},
{
info: {
id: "msg_newer_user",
role: "user",
},
parts: [{ type: "text", text: "new prompt after interrupted turn" }],
},
],
}),
promptAsync: async (call: PromptAsyncCall) => {
promptAsyncCalls.push(call)
return {}
},
},
},
directory: "/tmp/session-recovery-newer-user-test",
}
const hook = createSessionRecoveryHook(ctx as never)
// when
const result = await hook.handleInterruptedToolResultsOnIdle("ses_stale_after_user")
// then
expect(result).toBe(false)
expect(promptAsyncCalls).toHaveLength(0)
})
})
+5 -1
View File
@@ -95,7 +95,11 @@ export function createSessionRecoveryHook(ctx: PluginInput, options?: SessionRec
const findLatestAssistantMessage = (messages: MessageData[]): MessageData | undefined => {
for (let index = messages.length - 1; index >= 0; index--) {
const message = messages[index]
if (message?.info?.role === "assistant") {
const role = message?.info?.role
if (role === "user") {
return undefined
}
if (role === "assistant") {
return message
}
}