refactor(httpapi): scope async prompt fiber (#25213)

This commit is contained in:
Kit Langton
2026-04-30 22:33:02 -04:00
committed by GitHub
parent bce4def2db
commit 5ba68a28c0
@@ -19,7 +19,7 @@ import { Todo } from "@/session/todo"
import { MessageID, PartID, SessionID } from "@/session/schema" import { MessageID, PartID, SessionID } from "@/session/schema"
import { NotFoundError } from "@/storage/storage" import { NotFoundError } from "@/storage/storage"
import { NamedError } from "@opencode-ai/core/util/error" import { NamedError } from "@opencode-ai/core/util/error"
import { Cause, Effect, Schema } from "effect" import { Cause, Effect, Schema, Scope } from "effect"
import * as Stream from "effect/Stream" import * as Stream from "effect/Stream"
import { HttpServerRequest, HttpServerResponse } from "effect/unstable/http" import { HttpServerRequest, HttpServerResponse } from "effect/unstable/http"
import { HttpApiBuilder, HttpApiError, HttpApiSchema } from "effect/unstable/httpapi" import { HttpApiBuilder, HttpApiError, HttpApiSchema } from "effect/unstable/httpapi"
@@ -61,6 +61,7 @@ export const sessionHandlers = HttpApiBuilder.group(InstanceHttpApi, "session",
const todoSvc = yield* Todo.Service const todoSvc = yield* Todo.Service
const summary = yield* SessionSummary.Service const summary = yield* SessionSummary.Service
const bus = yield* Bus.Service const bus = yield* Bus.Service
const scope = yield* Scope.Scope
const list = Effect.fn("SessionHttpApi.list")(function* (ctx: { query: typeof ListQuery.Type }) { const list = Effect.fn("SessionHttpApi.list")(function* (ctx: { query: typeof ListQuery.Type }) {
const instance = yield* InstanceState.context const instance = yield* InstanceState.context
@@ -281,24 +282,17 @@ export const sessionHandlers = HttpApiBuilder.group(InstanceHttpApi, "session",
params: { sessionID: SessionID } params: { sessionID: SessionID }
payload: typeof PromptPayload.Type payload: typeof PromptPayload.Type
}) { }) {
const instance = yield* InstanceState.context yield* promptSvc.prompt({ ...ctx.payload, sessionID: ctx.params.sessionID }).pipe(
const workspace = yield* InstanceState.workspaceID Effect.catchCause((cause) =>
yield* Effect.sync(() => Effect.gen(function* () {
Effect.runFork( yield* Effect.logError("prompt_async failed", { sessionID: ctx.params.sessionID, cause })
promptSvc.prompt({ ...ctx.payload, sessionID: ctx.params.sessionID }).pipe( yield* bus.publish(Session.Event.Error, {
Effect.provideService(InstanceRef, instance), sessionID: ctx.params.sessionID,
Effect.provideService(WorkspaceRef, workspace), error: new NamedError.Unknown({ message: Cause.pretty(cause) }).toObject(),
Effect.catchCause((cause) => })
Effect.gen(function* () { }),
yield* Effect.logError("prompt_async failed", { sessionID: ctx.params.sessionID, cause })
yield* bus.publish(Session.Event.Error, {
sessionID: ctx.params.sessionID,
error: new NamedError.Unknown({ message: Cause.pretty(cause) }).toObject(),
})
}),
),
),
), ),
Effect.forkIn(scope, { startImmediately: true }),
) )
return HttpApiSchema.NoContent.make() return HttpApiSchema.NoContent.make()
}) })