fix(prompt-gate): hold reservations after dispatch
This commit is contained in:
@@ -56,6 +56,41 @@ describe("promptAsyncAfterSessionIdle", () => {
|
||||
expect(promptCalls).toBe(1)
|
||||
})
|
||||
|
||||
test("#given settle is disabled and status is unavailable #when a second promptAsync starts after the first dispatch resolves #then the default dispatch hold keeps the session reserved", async () => {
|
||||
// given
|
||||
let promptCalls = 0
|
||||
const client = {
|
||||
session: {
|
||||
promptAsync: async () => {
|
||||
promptCalls += 1
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// when
|
||||
const first = promptAsyncAfterSessionIdle({
|
||||
client,
|
||||
sessionID: "ses_hold_after_dispatch",
|
||||
input: { path: { id: "ses_hold_after_dispatch" }, body: { parts: [] } },
|
||||
source: "test:hold:first",
|
||||
settleMs: 0,
|
||||
})
|
||||
await new Promise((resolve) => setTimeout(resolve, 0))
|
||||
const second = await promptAsyncAfterSessionIdle({
|
||||
client,
|
||||
sessionID: "ses_hold_after_dispatch",
|
||||
input: { path: { id: "ses_hold_after_dispatch" }, body: { parts: [] } },
|
||||
source: "test:hold:second",
|
||||
settleMs: 0,
|
||||
})
|
||||
const firstResult = await first
|
||||
|
||||
// then
|
||||
expect(firstResult.status).toBe("dispatched")
|
||||
expect(second.status).toBe("reserved")
|
||||
expect(promptCalls).toBe(1)
|
||||
})
|
||||
|
||||
test("#given session.status reports busy #when an internal promptAsync is requested #then no prompt is sent", async () => {
|
||||
// given
|
||||
let promptCalls = 0
|
||||
@@ -126,4 +161,39 @@ describe("promptAsyncAfterSessionIdle", () => {
|
||||
expect(second.status).toBe("reserved")
|
||||
expect(promptCalls).toBe(1)
|
||||
})
|
||||
|
||||
test("#given settle is disabled and status is unavailable #when a second prompt starts after the first dispatch resolves #then the default dispatch hold keeps the session reserved", async () => {
|
||||
// given
|
||||
let promptCalls = 0
|
||||
const client = {
|
||||
session: {
|
||||
prompt: async () => {
|
||||
promptCalls += 1
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// when
|
||||
const first = promptAfterSessionIdle({
|
||||
client,
|
||||
sessionID: "ses_prompt_hold_after_dispatch",
|
||||
input: { path: { id: "ses_prompt_hold_after_dispatch" }, body: { parts: [] } },
|
||||
source: "test:prompt-hold:first",
|
||||
settleMs: 0,
|
||||
})
|
||||
await new Promise((resolve) => setTimeout(resolve, 0))
|
||||
const second = await promptAfterSessionIdle({
|
||||
client,
|
||||
sessionID: "ses_prompt_hold_after_dispatch",
|
||||
input: { path: { id: "ses_prompt_hold_after_dispatch" }, body: { parts: [] } },
|
||||
source: "test:prompt-hold:second",
|
||||
settleMs: 0,
|
||||
})
|
||||
const firstResult = await first
|
||||
|
||||
// then
|
||||
expect(firstResult.status).toBe("dispatched")
|
||||
expect(second.status).toBe("reserved")
|
||||
expect(promptCalls).toBe(1)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -60,9 +60,7 @@ export async function promptAsyncAfterSessionIdle<TInput = PromptAsyncInput>(arg
|
||||
source,
|
||||
settleMs = DEFAULT_SESSION_IDLE_SETTLE_MS,
|
||||
} = args
|
||||
const postDispatchHoldMs = args.postDispatchHoldMs ?? (
|
||||
settleMs > 0 ? DEFAULT_PROMPT_ASYNC_POST_DISPATCH_HOLD_MS : 0
|
||||
)
|
||||
const postDispatchHoldMs = args.postDispatchHoldMs ?? DEFAULT_PROMPT_ASYNC_POST_DISPATCH_HOLD_MS
|
||||
|
||||
if (typeof client.session?.promptAsync !== "function") {
|
||||
log("[prompt-async-gate] promptAsync unavailable", { sessionID, source })
|
||||
@@ -100,7 +98,7 @@ export async function promptAsyncAfterSessionIdle<TInput = PromptAsyncInput>(arg
|
||||
|
||||
log("[prompt-async-gate] promptAsync dispatching", { sessionID, source })
|
||||
const response = await client.session.promptAsync(input)
|
||||
if (canReadStatus) {
|
||||
if (postDispatchHoldMs > 0) {
|
||||
await settleAfterSessionIdle(postDispatchHoldMs)
|
||||
}
|
||||
log("[prompt-async-gate] promptAsync dispatched", { sessionID, source })
|
||||
@@ -132,9 +130,7 @@ export async function promptAfterSessionIdle<TInput = PromptAsyncInput>(args: {
|
||||
source,
|
||||
settleMs = DEFAULT_SESSION_IDLE_SETTLE_MS,
|
||||
} = args
|
||||
const postDispatchHoldMs = args.postDispatchHoldMs ?? (
|
||||
settleMs > 0 ? DEFAULT_PROMPT_ASYNC_POST_DISPATCH_HOLD_MS : 0
|
||||
)
|
||||
const postDispatchHoldMs = args.postDispatchHoldMs ?? DEFAULT_PROMPT_ASYNC_POST_DISPATCH_HOLD_MS
|
||||
|
||||
if (typeof client.session?.prompt !== "function") {
|
||||
log("[prompt-async-gate] prompt unavailable", { sessionID, source })
|
||||
@@ -172,7 +168,7 @@ export async function promptAfterSessionIdle<TInput = PromptAsyncInput>(args: {
|
||||
|
||||
log("[prompt-async-gate] prompt dispatching", { sessionID, source })
|
||||
const response = await client.session.prompt(input)
|
||||
if (canReadStatus) {
|
||||
if (postDispatchHoldMs > 0) {
|
||||
await settleAfterSessionIdle(postDispatchHoldMs)
|
||||
}
|
||||
log("[prompt-async-gate] prompt dispatched", { sessionID, source })
|
||||
|
||||
Reference in New Issue
Block a user