mirror of
https://github.com/anomalyco/opencode.git
synced 2026-07-17 12:56:41 +02:00
fix(opencode): settle interrupted question waits
This commit is contained in:
@@ -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) => ({
|
||||
|
||||
Reference in New Issue
Block a user