diff --git a/packages/opencode/src/session/instruction.ts b/packages/opencode/src/session/instruction.ts index 9b01c9524f..04f2610dfe 100644 --- a/packages/opencode/src/session/instruction.ts +++ b/packages/opencode/src/session/instruction.ts @@ -4,7 +4,6 @@ import { Effect, Layer, Context } from "effect" import { FetchHttpClient, HttpClient, HttpClientRequest } from "effect/unstable/http" import { Config } from "@/config/config" import { InstanceState } from "@/effect/instance-state" -import { makeRuntime } from "@/effect/run-service" import { Flag } from "@/flag/flag" import { AppFileSystem } from "@/filesystem" import { withTransientReadRetry } from "@/util/effect-http-client" @@ -238,21 +237,7 @@ export namespace Instruction { Layer.provide(FetchHttpClient.layer), ) - const { runPromise } = makeRuntime(Service, defaultLayer) - - export function clear(messageID: MessageID) { - return runPromise((svc) => svc.clear(messageID)) - } - - export async function systemPaths() { - return runPromise((svc) => svc.systemPaths()) - } - export function loaded(messages: MessageV2.WithParts[]) { return extract(messages) } - - export async function resolve(messages: MessageV2.WithParts[], filepath: string, messageID: MessageID) { - return runPromise((svc) => svc.resolve(messages, filepath, messageID)) - } } diff --git a/packages/opencode/test/session/instruction.test.ts b/packages/opencode/test/session/instruction.test.ts index a8c25c6f0e..4ba3b78e42 100644 --- a/packages/opencode/test/session/instruction.test.ts +++ b/packages/opencode/test/session/instruction.test.ts @@ -1,5 +1,6 @@ import { afterEach, beforeEach, describe, expect, test } from "bun:test" import path from "path" +import { Effect } from "effect" import { ModelID, ProviderID } from "../../src/provider/schema" import { Instruction } from "../../src/session/instruction" import type { MessageV2 } from "../../src/session/message-v2" @@ -8,6 +9,9 @@ import { MessageID, PartID, SessionID } from "../../src/session/schema" import { Global } from "../../src/global" import { tmpdir } from "../fixture/fixture" +const run = (effect: Effect.Effect) => + Effect.runPromise(effect.pipe(Effect.provide(Instruction.defaultLayer))) + function loaded(filepath: string): MessageV2.WithParts[] { const sessionID = SessionID.make("session-loaded-1") const messageID = MessageID.make("message-loaded-1") @@ -57,17 +61,22 @@ describe("Instruction.resolve", () => { }) await Instance.provide({ directory: tmp.path, - fn: async () => { - const system = await Instruction.systemPaths() - expect(system.has(path.join(tmp.path, "AGENTS.md"))).toBe(true) + fn: () => + run( + Instruction.Service.use((svc) => + Effect.gen(function* () { + const system = yield* svc.systemPaths() + expect(system.has(path.join(tmp.path, "AGENTS.md"))).toBe(true) - const results = await Instruction.resolve( - [], - path.join(tmp.path, "src", "file.ts"), - MessageID.make("message-test-1"), - ) - expect(results).toEqual([]) - }, + const results = yield* svc.resolve( + [], + path.join(tmp.path, "src", "file.ts"), + MessageID.make("message-test-1"), + ) + expect(results).toEqual([]) + }), + ), + ), }) }) @@ -80,18 +89,23 @@ describe("Instruction.resolve", () => { }) await Instance.provide({ directory: tmp.path, - fn: async () => { - const system = await Instruction.systemPaths() - expect(system.has(path.join(tmp.path, "subdir", "AGENTS.md"))).toBe(false) + fn: () => + run( + Instruction.Service.use((svc) => + Effect.gen(function* () { + const system = yield* svc.systemPaths() + expect(system.has(path.join(tmp.path, "subdir", "AGENTS.md"))).toBe(false) - const results = await Instruction.resolve( - [], - path.join(tmp.path, "subdir", "nested", "file.ts"), - MessageID.make("message-test-2"), - ) - expect(results.length).toBe(1) - expect(results[0].filepath).toBe(path.join(tmp.path, "subdir", "AGENTS.md")) - }, + const results = yield* svc.resolve( + [], + path.join(tmp.path, "subdir", "nested", "file.ts"), + MessageID.make("message-test-2"), + ) + expect(results.length).toBe(1) + expect(results[0].filepath).toBe(path.join(tmp.path, "subdir", "AGENTS.md")) + }), + ), + ), }) }) @@ -104,14 +118,19 @@ describe("Instruction.resolve", () => { }) await Instance.provide({ directory: tmp.path, - fn: async () => { - const filepath = path.join(tmp.path, "subdir", "AGENTS.md") - const system = await Instruction.systemPaths() - expect(system.has(filepath)).toBe(false) + fn: () => + run( + Instruction.Service.use((svc) => + Effect.gen(function* () { + const filepath = path.join(tmp.path, "subdir", "AGENTS.md") + const system = yield* svc.systemPaths() + expect(system.has(filepath)).toBe(false) - const results = await Instruction.resolve([], filepath, MessageID.make("message-test-3")) - expect(results).toEqual([]) - }, + const results = yield* svc.resolve([], filepath, MessageID.make("message-test-3")) + expect(results).toEqual([]) + }), + ), + ), }) }) @@ -124,17 +143,22 @@ describe("Instruction.resolve", () => { }) await Instance.provide({ directory: tmp.path, - fn: async () => { - const filepath = path.join(tmp.path, "subdir", "nested", "file.ts") - const id = MessageID.make("message-claim-1") + fn: () => + run( + Instruction.Service.use((svc) => + Effect.gen(function* () { + const filepath = path.join(tmp.path, "subdir", "nested", "file.ts") + const id = MessageID.make("message-claim-1") - const first = await Instruction.resolve([], filepath, id) - const second = await Instruction.resolve([], filepath, id) + const first = yield* svc.resolve([], filepath, id) + const second = yield* svc.resolve([], filepath, id) - expect(first).toHaveLength(1) - expect(first[0].filepath).toBe(path.join(tmp.path, "subdir", "AGENTS.md")) - expect(second).toEqual([]) - }, + expect(first).toHaveLength(1) + expect(first[0].filepath).toBe(path.join(tmp.path, "subdir", "AGENTS.md")) + expect(second).toEqual([]) + }), + ), + ), }) }) @@ -147,18 +171,23 @@ describe("Instruction.resolve", () => { }) await Instance.provide({ directory: tmp.path, - fn: async () => { - const filepath = path.join(tmp.path, "subdir", "nested", "file.ts") - const id = MessageID.make("message-claim-2") + fn: () => + run( + Instruction.Service.use((svc) => + Effect.gen(function* () { + const filepath = path.join(tmp.path, "subdir", "nested", "file.ts") + const id = MessageID.make("message-claim-2") - const first = await Instruction.resolve([], filepath, id) - await Instruction.clear(id) - const second = await Instruction.resolve([], filepath, id) + const first = yield* svc.resolve([], filepath, id) + yield* svc.clear(id) + const second = yield* svc.resolve([], filepath, id) - expect(first).toHaveLength(1) - expect(second).toHaveLength(1) - expect(second[0].filepath).toBe(path.join(tmp.path, "subdir", "AGENTS.md")) - }, + expect(first).toHaveLength(1) + expect(second).toHaveLength(1) + expect(second[0].filepath).toBe(path.join(tmp.path, "subdir", "AGENTS.md")) + }), + ), + ), }) }) @@ -171,15 +200,19 @@ describe("Instruction.resolve", () => { }) await Instance.provide({ directory: tmp.path, - fn: async () => { - const agents = path.join(tmp.path, "subdir", "AGENTS.md") - const filepath = path.join(tmp.path, "subdir", "nested", "file.ts") - const id = MessageID.make("message-claim-3") + fn: () => + run( + Instruction.Service.use((svc) => + Effect.gen(function* () { + const agents = path.join(tmp.path, "subdir", "AGENTS.md") + const filepath = path.join(tmp.path, "subdir", "nested", "file.ts") + const id = MessageID.make("message-claim-3") - const results = await Instruction.resolve(loaded(agents), filepath, id) - - expect(results).toEqual([]) - }, + const results = yield* svc.resolve(loaded(agents), filepath, id) + expect(results).toEqual([]) + }), + ), + ), }) }) @@ -221,11 +254,16 @@ describe("Instruction.systemPaths OPENCODE_CONFIG_DIR", () => { try { await Instance.provide({ directory: projectTmp.path, - fn: async () => { - const paths = await Instruction.systemPaths() - expect(paths.has(path.join(profileTmp.path, "AGENTS.md"))).toBe(true) - expect(paths.has(path.join(globalTmp.path, "AGENTS.md"))).toBe(false) - }, + fn: () => + run( + Instruction.Service.use((svc) => + Effect.gen(function* () { + const paths = yield* svc.systemPaths() + expect(paths.has(path.join(profileTmp.path, "AGENTS.md"))).toBe(true) + expect(paths.has(path.join(globalTmp.path, "AGENTS.md"))).toBe(false) + }), + ), + ), }) } finally { ;(Global.Path as { config: string }).config = originalGlobalConfig @@ -248,11 +286,16 @@ describe("Instruction.systemPaths OPENCODE_CONFIG_DIR", () => { try { await Instance.provide({ directory: projectTmp.path, - fn: async () => { - const paths = await Instruction.systemPaths() - expect(paths.has(path.join(profileTmp.path, "AGENTS.md"))).toBe(false) - expect(paths.has(path.join(globalTmp.path, "AGENTS.md"))).toBe(true) - }, + fn: () => + run( + Instruction.Service.use((svc) => + Effect.gen(function* () { + const paths = yield* svc.systemPaths() + expect(paths.has(path.join(profileTmp.path, "AGENTS.md"))).toBe(false) + expect(paths.has(path.join(globalTmp.path, "AGENTS.md"))).toBe(true) + }), + ), + ), }) } finally { ;(Global.Path as { config: string }).config = originalGlobalConfig @@ -274,10 +317,15 @@ describe("Instruction.systemPaths OPENCODE_CONFIG_DIR", () => { try { await Instance.provide({ directory: projectTmp.path, - fn: async () => { - const paths = await Instruction.systemPaths() - expect(paths.has(path.join(globalTmp.path, "AGENTS.md"))).toBe(true) - }, + fn: () => + run( + Instruction.Service.use((svc) => + Effect.gen(function* () { + const paths = yield* svc.systemPaths() + expect(paths.has(path.join(globalTmp.path, "AGENTS.md"))).toBe(true) + }), + ), + ), }) } finally { ;(Global.Path as { config: string }).config = originalGlobalConfig