Parcourir la source

refactor(session): destroy Instruction facade (#22089)

Kit Langton il y a 5 jours
Parent
commit
eea4253d67

+ 0 - 15
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))
-  }
 }

+ 117 - 69
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 = <A>(effect: Effect.Effect<A, any, Instruction.Service>) =>
+  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