fix(prompt-gate): share message reservations

This commit is contained in:
YeonGyu-Kim
2026-05-15 11:49:44 +09:00
parent dd6271bbf4
commit 30adce9cad
9 changed files with 451 additions and 196 deletions
+54 -14
View File
@@ -5,6 +5,7 @@ import {
PROMPT_TIMEOUT_MS,
type PromptRetryOptions,
} from "./prompt-timeout-context"
import { promptAfterSessionIdle, promptAsyncAfterSessionIdle } from "./prompt-async-gate"
type Client = ReturnType<typeof createOpencodeClient>
@@ -93,14 +94,25 @@ export async function promptWithModelSuggestionRetry(
): Promise<void> {
const timeoutMs = options.timeoutMs ?? PROMPT_TIMEOUT_MS
const timeoutContext = createPromptTimeoutContext(args, timeoutMs)
// model errors happen asynchronously server-side and cannot be caught here
const promptPromise = client.session.promptAsync({
...args,
signal: timeoutContext.signal,
} as Parameters<typeof client.session.promptAsync>[0])
try {
await promptPromise
const promptResult = await promptAsyncAfterSessionIdle({
client,
sessionID: args.path.id,
input: {
...args,
signal: timeoutContext.signal,
} as Parameters<typeof client.session.promptAsync>[0],
source: "model-suggestion-retry",
settleMs: 0,
postDispatchHoldMs: 0,
})
if (promptResult.status === "failed") {
throw promptResult.error
}
if (promptResult.status !== "dispatched") {
throw new Error(`promptAsync skipped by gate: ${promptResult.status}`)
}
if (timeoutContext.wasTimedOut()) {
throw new Error(`promptAsync timed out after ${timeoutMs}ms`)
}
@@ -124,10 +136,24 @@ export async function promptSyncWithModelSuggestionRetry(
try {
const timeoutContext = createPromptTimeoutContext(args, timeoutMs)
try {
await client.session.prompt({
...args,
signal: timeoutContext.signal,
} as Parameters<typeof client.session.prompt>[0])
const promptResult = await promptAfterSessionIdle({
client,
sessionID: args.path.id,
input: {
...args,
signal: timeoutContext.signal,
} as Parameters<typeof client.session.prompt>[0],
source: "model-suggestion-retry:sync",
settleMs: 0,
postDispatchHoldMs: 0,
checkStatus: false,
})
if (promptResult.status === "failed") {
throw promptResult.error
}
if (promptResult.status !== "dispatched") {
throw new Error(`prompt skipped by gate: ${promptResult.status}`)
}
if (timeoutContext.wasTimedOut()) {
throw new Error(`prompt timed out after ${timeoutMs}ms`)
}
@@ -163,10 +189,24 @@ export async function promptSyncWithModelSuggestionRetry(
const timeoutContext = createPromptTimeoutContext(retryArgs, timeoutMs)
try {
await client.session.prompt({
...retryArgs,
signal: timeoutContext.signal,
} as Parameters<typeof client.session.prompt>[0])
const promptResult = await promptAfterSessionIdle({
client,
sessionID: retryArgs.path.id,
input: {
...retryArgs,
signal: timeoutContext.signal,
} as Parameters<typeof client.session.prompt>[0],
source: "model-suggestion-retry:sync-retry",
settleMs: 0,
postDispatchHoldMs: 0,
checkStatus: false,
})
if (promptResult.status === "failed") {
throw promptResult.error
}
if (promptResult.status !== "dispatched") {
throw new Error(`prompt skipped by gate: ${promptResult.status}`)
}
if (timeoutContext.wasTimedOut()) {
throw new Error(`prompt timed out after ${timeoutMs}ms`)
}