fix(opencode): settle interrupted question waits

This commit is contained in:
Aiden Cline
2026-05-25 01:06:41 -05:00
parent 08bef1696d
commit c28ea79662
3 changed files with 62 additions and 0 deletions
+8
View File
@@ -218,7 +218,15 @@ export const layer = Layer.effect(
wait(request.id).pipe(Effect.orDie),
Effect.gen(function* () {
const info = yield* InstanceState.get(state)
const existing = info.pending.get(request.id)
if (!existing) return
yield* Cache.set(info.completed, request.id, { status: "rejected" })
info.pending.delete(request.id)
yield* bus.publish(Event.Rejected, {
sessionID: existing.info.sessionID,
requestID: existing.info.id,
})
yield* Deferred.succeed(existing.deferred, { status: "rejected" })
}),
)
if (result.status === "answered") return result.answers
@@ -229,6 +229,32 @@ it.instance(
{ git: true },
)
it.instance(
"wait - returns rejected when pending ask is interrupted",
() =>
Effect.gen(function* () {
const fiber = yield* askEffect({
sessionID: SessionID.make("ses_test"),
questions: [
{
question: "What would you like to do?",
header: "Action",
options: [{ label: "Option 1", description: "First option" }],
},
],
}).pipe(Effect.forkScoped)
const pending = yield* waitForPending(1)
const waiter = yield* waitEffect(pending[0].id).pipe(Effect.forkScoped)
yield* Fiber.interrupt(fiber)
expect(yield* Fiber.join(waiter)).toEqual({ status: "rejected" })
expect(yield* waitEffect(pending[0].id)).toEqual({ status: "rejected" })
}),
{ git: true },
)
it.instance(
"reply - fails for unknown requestID",
() =>
@@ -235,6 +235,34 @@ const scenarios: Scenario[] = [
}))
.json(404, object, "status"),
http.protected.get("/question", "question.list").json(200, array),
http.protected
.post("/question", "question.ask")
.mutating()
.at((ctx) => ({
path: "/question",
headers: ctx.headers(),
body: {
sessionID: "ses_httpapi_question",
questions: [
{
question: "Proceed?",
header: "Proceed",
options: [{ label: "Yes", description: "Continue" }],
},
],
},
}))
.json(200, (body) => {
object(body)
check(typeof body.id === "string" && body.id.startsWith("que_"), "question ask should return request id")
}),
http.protected
.get("/question/{requestID}/wait", "question.wait.missing")
.at((ctx) => ({
path: route("/question/{requestID}/wait", { requestID: "que_httpapi_wait" }),
headers: ctx.headers(),
}))
.json(404, object, "status"),
http.protected
.post("/question/{requestID}/reply", "question.reply.invalid")
.at((ctx) => ({