From 5ba68a28c02a95e8359deefa9ee2806f84169e40 Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Thu, 30 Apr 2026 22:33:02 -0400 Subject: [PATCH] refactor(httpapi): scope async prompt fiber (#25213) --- .../instance/httpapi/handlers/session.ts | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/packages/opencode/src/server/routes/instance/httpapi/handlers/session.ts b/packages/opencode/src/server/routes/instance/httpapi/handlers/session.ts index 384550d1cc..cd8b5e11c2 100644 --- a/packages/opencode/src/server/routes/instance/httpapi/handlers/session.ts +++ b/packages/opencode/src/server/routes/instance/httpapi/handlers/session.ts @@ -19,7 +19,7 @@ import { Todo } from "@/session/todo" import { MessageID, PartID, SessionID } from "@/session/schema" import { NotFoundError } from "@/storage/storage" 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 { HttpServerRequest, HttpServerResponse } from "effect/unstable/http" 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 summary = yield* SessionSummary.Service const bus = yield* Bus.Service + const scope = yield* Scope.Scope const list = Effect.fn("SessionHttpApi.list")(function* (ctx: { query: typeof ListQuery.Type }) { const instance = yield* InstanceState.context @@ -281,24 +282,17 @@ export const sessionHandlers = HttpApiBuilder.group(InstanceHttpApi, "session", params: { sessionID: SessionID } payload: typeof PromptPayload.Type }) { - const instance = yield* InstanceState.context - const workspace = yield* InstanceState.workspaceID - yield* Effect.sync(() => - Effect.runFork( - promptSvc.prompt({ ...ctx.payload, sessionID: ctx.params.sessionID }).pipe( - Effect.provideService(InstanceRef, instance), - Effect.provideService(WorkspaceRef, workspace), - 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(), - }) - }), - ), - ), + yield* promptSvc.prompt({ ...ctx.payload, sessionID: ctx.params.sessionID }).pipe( + 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() })