fix(prompt-gate): hold reservations after dispatch
This commit is contained in:
@@ -56,6 +56,41 @@ describe("promptAsyncAfterSessionIdle", () => {
|
|||||||
expect(promptCalls).toBe(1)
|
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 () => {
|
test("#given session.status reports busy #when an internal promptAsync is requested #then no prompt is sent", async () => {
|
||||||
// given
|
// given
|
||||||
let promptCalls = 0
|
let promptCalls = 0
|
||||||
@@ -126,4 +161,39 @@ describe("promptAsyncAfterSessionIdle", () => {
|
|||||||
expect(second.status).toBe("reserved")
|
expect(second.status).toBe("reserved")
|
||||||
expect(promptCalls).toBe(1)
|
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,
|
source,
|
||||||
settleMs = DEFAULT_SESSION_IDLE_SETTLE_MS,
|
settleMs = DEFAULT_SESSION_IDLE_SETTLE_MS,
|
||||||
} = args
|
} = args
|
||||||
const postDispatchHoldMs = args.postDispatchHoldMs ?? (
|
const postDispatchHoldMs = args.postDispatchHoldMs ?? DEFAULT_PROMPT_ASYNC_POST_DISPATCH_HOLD_MS
|
||||||
settleMs > 0 ? DEFAULT_PROMPT_ASYNC_POST_DISPATCH_HOLD_MS : 0
|
|
||||||
)
|
|
||||||
|
|
||||||
if (typeof client.session?.promptAsync !== "function") {
|
if (typeof client.session?.promptAsync !== "function") {
|
||||||
log("[prompt-async-gate] promptAsync unavailable", { sessionID, source })
|
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 })
|
log("[prompt-async-gate] promptAsync dispatching", { sessionID, source })
|
||||||
const response = await client.session.promptAsync(input)
|
const response = await client.session.promptAsync(input)
|
||||||
if (canReadStatus) {
|
if (postDispatchHoldMs > 0) {
|
||||||
await settleAfterSessionIdle(postDispatchHoldMs)
|
await settleAfterSessionIdle(postDispatchHoldMs)
|
||||||
}
|
}
|
||||||
log("[prompt-async-gate] promptAsync dispatched", { sessionID, source })
|
log("[prompt-async-gate] promptAsync dispatched", { sessionID, source })
|
||||||
@@ -132,9 +130,7 @@ export async function promptAfterSessionIdle<TInput = PromptAsyncInput>(args: {
|
|||||||
source,
|
source,
|
||||||
settleMs = DEFAULT_SESSION_IDLE_SETTLE_MS,
|
settleMs = DEFAULT_SESSION_IDLE_SETTLE_MS,
|
||||||
} = args
|
} = args
|
||||||
const postDispatchHoldMs = args.postDispatchHoldMs ?? (
|
const postDispatchHoldMs = args.postDispatchHoldMs ?? DEFAULT_PROMPT_ASYNC_POST_DISPATCH_HOLD_MS
|
||||||
settleMs > 0 ? DEFAULT_PROMPT_ASYNC_POST_DISPATCH_HOLD_MS : 0
|
|
||||||
)
|
|
||||||
|
|
||||||
if (typeof client.session?.prompt !== "function") {
|
if (typeof client.session?.prompt !== "function") {
|
||||||
log("[prompt-async-gate] prompt unavailable", { sessionID, source })
|
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 })
|
log("[prompt-async-gate] prompt dispatching", { sessionID, source })
|
||||||
const response = await client.session.prompt(input)
|
const response = await client.session.prompt(input)
|
||||||
if (canReadStatus) {
|
if (postDispatchHoldMs > 0) {
|
||||||
await settleAfterSessionIdle(postDispatchHoldMs)
|
await settleAfterSessionIdle(postDispatchHoldMs)
|
||||||
}
|
}
|
||||||
log("[prompt-async-gate] prompt dispatched", { sessionID, source })
|
log("[prompt-async-gate] prompt dispatched", { sessionID, source })
|
||||||
|
|||||||
Reference in New Issue
Block a user