summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorKit Langton <[email protected]>2026-04-14 17:33:44 -0400
committerGitHub <[email protected]>2026-04-14 17:33:44 -0400
commitaeb7d99d208bdd5e72278d16ed49c17479196a80 (patch)
treec316dd6b0cd041b083147821be897721c0007f26
parent3695057bee6a2d6810e4b569632d6e49b7522d6f (diff)
downloadopencode-aeb7d99d208bdd5e72278d16ed49c17479196a80.tar.gz
opencode-aeb7d99d208bdd5e72278d16ed49c17479196a80.zip
fix(effect): preserve logger context in prompt runs (#22496)
-rw-r--r--packages/opencode/src/effect/app-runtime.ts4
-rw-r--r--packages/opencode/src/session/prompt.ts6
-rw-r--r--packages/opencode/test/effect/app-runtime-logger.test.ts42
3 files changed, 47 insertions, 5 deletions
diff --git a/packages/opencode/src/effect/app-runtime.ts b/packages/opencode/src/effect/app-runtime.ts
index 9e1fb8bd2..674ca1a2a 100644
--- a/packages/opencode/src/effect/app-runtime.ts
+++ b/packages/opencode/src/effect/app-runtime.ts
@@ -49,7 +49,7 @@ import { ShareNext } from "@/share/share-next"
import { SessionShare } from "@/share/session"
export const AppLayer = Layer.mergeAll(
- // Observability.layer,
+ Observability.layer,
AppFileSystem.defaultLayer,
Bus.defaultLayer,
Auth.defaultLayer,
@@ -95,6 +95,6 @@ export const AppLayer = Layer.mergeAll(
Installation.defaultLayer,
ShareNext.defaultLayer,
SessionShare.defaultLayer,
-).pipe(Layer.provide(Observability.layer))
+)
export const AppRuntime = ManagedRuntime.make(AppLayer, { memoMap })
diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts
index 4b0c30802..a763b27b9 100644
--- a/packages/opencode/src/session/prompt.ts
+++ b/packages/opencode/src/session/prompt.ts
@@ -104,11 +104,11 @@ export namespace SessionPrompt {
const summary = yield* SessionSummary.Service
const sys = yield* SystemPrompt.Service
const llm = yield* LLM.Service
+ const ctx = yield* Effect.context()
const run = {
- promise: <A, E>(effect: Effect.Effect<A, E>) =>
- Effect.runPromise(effect.pipe(Effect.provide(EffectLogger.layer))),
- fork: <A, E>(effect: Effect.Effect<A, E>) => Effect.runFork(effect.pipe(Effect.provide(EffectLogger.layer))),
+ promise: <A, E>(effect: Effect.Effect<A, E>) => Effect.runPromiseWith(ctx)(effect),
+ fork: <A, E>(effect: Effect.Effect<A, E>) => Effect.runForkWith(ctx)(effect),
}
const cancel = Effect.fn("SessionPrompt.cancel")(function* (sessionID: SessionID) {
diff --git a/packages/opencode/test/effect/app-runtime-logger.test.ts b/packages/opencode/test/effect/app-runtime-logger.test.ts
new file mode 100644
index 000000000..c09775be3
--- /dev/null
+++ b/packages/opencode/test/effect/app-runtime-logger.test.ts
@@ -0,0 +1,42 @@
+import { expect, test } from "bun:test"
+import { Context, Effect, Layer, Logger } from "effect"
+import { AppRuntime } from "../../src/effect/app-runtime"
+import { EffectLogger } from "../../src/effect/logger"
+import { makeRuntime } from "../../src/effect/run-service"
+
+function check(loggers: ReadonlySet<Logger.Logger<unknown, any>>) {
+ return {
+ defaultLogger: loggers.has(Logger.defaultLogger),
+ tracerLogger: loggers.has(Logger.tracerLogger),
+ effectLogger: loggers.has(EffectLogger.logger),
+ size: loggers.size,
+ }
+}
+
+test("makeRuntime installs EffectLogger through Observability.layer", async () => {
+ class Dummy extends Context.Service<Dummy, { readonly current: () => Effect.Effect<ReturnType<typeof check>> }>()(
+ "@test/Dummy",
+ ) {}
+
+ const layer = Layer.effect(
+ Dummy,
+ Effect.gen(function* () {
+ return Dummy.of({
+ current: () => Effect.map(Effect.service(Logger.CurrentLoggers), check),
+ })
+ }),
+ )
+
+ const rt = makeRuntime(Dummy, layer)
+ const current = await rt.runPromise((svc) => svc.current())
+
+ expect(current.effectLogger).toBe(true)
+ expect(current.defaultLogger).toBe(false)
+})
+
+test("AppRuntime also installs EffectLogger through Observability.layer", async () => {
+ const current = await AppRuntime.runPromise(Effect.map(Effect.service(Logger.CurrentLoggers), check))
+
+ expect(current.effectLogger).toBe(true)
+ expect(current.defaultLogger).toBe(false)
+})