fix(session-recovery): gate resume prompts

This commit is contained in:
YeonGyu-Kim
2026-05-15 11:30:07 +09:00
parent db28a32cff
commit b0a484b403
3 changed files with 40 additions and 13 deletions
@@ -3,11 +3,13 @@ import type { MessageData, ResumeConfig } from "./types"
import { readParts } from "./storage"
import { isSqliteBackend } from "../../shared/opencode-storage-detection"
import { normalizeSDKResponse } from "../../shared"
import { promptAsyncAfterSessionIdle } from "../shared/prompt-async-gate"
type Client = ReturnType<typeof createOpencodeClient>
type ClientWithPromptAsync = {
session: {
promptAsync: (opts: { path: { id: string }; body: Record<string, unknown> }) => Promise<unknown>
status?: () => Promise<unknown>
}
}
@@ -119,9 +121,14 @@ export async function recoverToolResultMissing(
return false
}
await client.session.promptAsync(promptInput)
const promptResult = await promptAsyncAfterSessionIdle({
client,
sessionID,
source: "session-recovery-tool-result-missing",
input: promptInput,
})
return true
return promptResult.status === "dispatched"
} catch {
return false
}
@@ -4,6 +4,7 @@ import { readParts } from "./storage"
import type { MessageData } from "./types"
import { normalizeSDKResponse } from "../../shared"
import { isSqliteBackend } from "../../shared/opencode-storage-detection"
import { promptAsyncAfterSessionIdle } from "../shared/prompt-async-gate"
type Client = ReturnType<typeof createOpencodeClient>
@@ -100,8 +101,21 @@ export async function recoverUnavailableTool(
body: { parts: toolResultParts },
}
const promptAsync = client.session.promptAsync as (...args: never[]) => unknown
await Reflect.apply(promptAsync, client.session, [promptInput])
return true
const promptClient = {
session: {
status: client.session.status,
promptAsync: (input: PromptWithToolResultInput) => (
Reflect.apply(promptAsync, client.session, [input]) as Promise<unknown>
),
},
}
const promptResult = await promptAsyncAfterSessionIdle<PromptWithToolResultInput>({
client: promptClient,
sessionID,
source: "session-recovery-unavailable-tool",
input: promptInput,
})
return promptResult.status === "dispatched"
} catch {
return false
}
+15 -9
View File
@@ -1,6 +1,7 @@
import type { createOpencodeClient } from "@opencode-ai/sdk"
import type { MessageData, ResumeConfig } from "./types"
import { createInternalAgentContinuationTextPart, resolveInheritedPromptTools } from "../../shared"
import { promptAsyncAfterSessionIdle } from "../shared/prompt-async-gate"
const RECOVERY_RESUME_TEXT = "[session recovered - continuing previous task]"
@@ -32,17 +33,22 @@ export async function resumeSession(client: Client, config: ResumeConfig): Promi
: undefined
const launchVariant = config.model?.variant
await client.session.promptAsync({
path: { id: config.sessionID },
body: {
parts: [createInternalAgentContinuationTextPart(RECOVERY_RESUME_TEXT)],
agent: config.agent,
...(launchModel ? { model: launchModel } : {}),
...(launchVariant ? { variant: launchVariant } : {}),
...(inheritedTools ? { tools: inheritedTools } : {}),
const promptResult = await promptAsyncAfterSessionIdle({
client,
sessionID: config.sessionID,
source: "session-recovery",
input: {
path: { id: config.sessionID },
body: {
parts: [createInternalAgentContinuationTextPart(RECOVERY_RESUME_TEXT)],
agent: config.agent,
...(launchModel ? { model: launchModel } : {}),
...(launchVariant ? { variant: launchVariant } : {}),
...(inheritedTools ? { tools: inheritedTools } : {}),
},
},
})
return true
return promptResult.status === "dispatched"
} catch {
return false
}