Sfoglia il codice sorgente

refactor(tool): yield Truncate and Agent in Tool.define, close over in wrap

Services are resolved at define-time (in registry context), passed into
wrap as closed-over values. Info.init() and Tool.init() stay R=never.
Tests updated to provide Truncate.defaultLayer and Agent.defaultLayer.
Kit Langton 6 giorni fa
parent
commit
a550ebf682

+ 1 - 8
packages/opencode/test/tool/apply_patch.test.ts

@@ -14,14 +14,7 @@ import { tmpdir } from "../fixture/fixture"
 import { SessionID, MessageID } from "../../src/session/schema"
 
 const runtime = ManagedRuntime.make(
-  Layer.mergeAll(
-    LSP.defaultLayer,
-    AppFileSystem.defaultLayer,
-    Format.defaultLayer,
-    Bus.layer,
-    Truncate.defaultLayer,
-    Agent.defaultLayer,
-  ),
+  Layer.mergeAll(LSP.defaultLayer, AppFileSystem.defaultLayer, Format.defaultLayer, Bus.layer, Truncate.defaultLayer, Agent.defaultLayer),
 )
 
 const baseCtx = {

+ 1 - 9
packages/opencode/test/tool/edit.test.ts

@@ -36,15 +36,7 @@ async function touch(file: string, time: number) {
 }
 
 const runtime = ManagedRuntime.make(
-  Layer.mergeAll(
-    LSP.defaultLayer,
-    FileTime.defaultLayer,
-    AppFileSystem.defaultLayer,
-    Format.defaultLayer,
-    Bus.layer,
-    Truncate.defaultLayer,
-    Agent.defaultLayer,
-  ),
+  Layer.mergeAll(LSP.defaultLayer, FileTime.defaultLayer, AppFileSystem.defaultLayer, Format.defaultLayer, Bus.layer, Truncate.defaultLayer, Agent.defaultLayer),
 )
 
 afterAll(async () => {

+ 1 - 3
packages/opencode/test/tool/grep.test.ts

@@ -9,9 +9,7 @@ import * as CrossSpawnSpawner from "../../src/effect/cross-spawn-spawner"
 import { Truncate } from "../../src/tool/truncate"
 import { Agent } from "../../src/agent/agent"
 
-const runtime = ManagedRuntime.make(
-  Layer.mergeAll(CrossSpawnSpawner.defaultLayer, Truncate.defaultLayer, Agent.defaultLayer),
-)
+const runtime = ManagedRuntime.make(Layer.mergeAll(CrossSpawnSpawner.defaultLayer, Truncate.defaultLayer, Agent.defaultLayer))
 
 function initGrep() {
   return runtime.runPromise(GrepTool.pipe(Effect.flatMap((info) => info.init())))

+ 1 - 3
packages/opencode/test/tool/question.test.ts

@@ -21,9 +21,7 @@ const ctx = {
   ask: () => Effect.void,
 }
 
-const it = testEffect(
-  Layer.mergeAll(Question.defaultLayer, CrossSpawnSpawner.defaultLayer, Truncate.defaultLayer, Agent.defaultLayer),
-)
+const it = testEffect(Layer.mergeAll(Question.defaultLayer, CrossSpawnSpawner.defaultLayer, Truncate.defaultLayer, Agent.defaultLayer))
 
 const pending = Effect.fn("QuestionToolTest.pending")(function* (question: Question.Interface) {
   for (;;) {

+ 1 - 3
packages/opencode/test/tool/skill.test.ts

@@ -152,9 +152,7 @@ Use this skill.
       await Instance.provide({
         directory: tmp.path,
         fn: async () => {
-          const runtime = ManagedRuntime.make(
-            Layer.mergeAll(Skill.defaultLayer, Ripgrep.defaultLayer, Truncate.defaultLayer, Agent.defaultLayer),
-          )
+          const runtime = ManagedRuntime.make(Layer.mergeAll(Skill.defaultLayer, Ripgrep.defaultLayer, Truncate.defaultLayer, Agent.defaultLayer))
           const info = await runtime.runPromise(SkillTool)
           const tool = await runtime.runPromise(info.init())
           const requests: Array<Omit<Permission.Request, "id" | "sessionID" | "tool">> = []

+ 13 - 5
packages/opencode/test/tool/webfetch.test.ts

@@ -26,10 +26,9 @@ async function withFetch(fetch: (req: Request) => Response | Promise<Response>,
   await fn(server.url)
 }
 
-function exec(args: { url: string; format: "text" | "markdown" | "html" }) {
+function initTool() {
   return WebFetchTool.pipe(
     Effect.flatMap((info) => info.init()),
-    Effect.flatMap((tool) => tool.execute(args, ctx)),
     Effect.provide(Layer.mergeAll(FetchHttpClient.layer, Truncate.defaultLayer, Agent.defaultLayer)),
     Effect.runPromise,
   )
@@ -44,7 +43,10 @@ describe("tool.webfetch", () => {
         await Instance.provide({
           directory: projectRoot,
           fn: async () => {
-            const result = await exec({ url: new URL("/image.png", url).toString(), format: "markdown" })
+            const webfetch = await initTool()
+            const result = await Effect.runPromise(
+              webfetch.execute({ url: new URL("/image.png", url).toString(), format: "markdown" }, ctx),
+            )
             expect(result.output).toBe("Image fetched successfully")
             expect(result.attachments).toBeDefined()
             expect(result.attachments?.length).toBe(1)
@@ -72,7 +74,10 @@ describe("tool.webfetch", () => {
         await Instance.provide({
           directory: projectRoot,
           fn: async () => {
-            const result = await exec({ url: new URL("/image.svg", url).toString(), format: "html" })
+            const webfetch = await initTool()
+            const result = await Effect.runPromise(
+              webfetch.execute({ url: new URL("/image.svg", url).toString(), format: "html" }, ctx),
+            )
             expect(result.output).toContain("<svg")
             expect(result.attachments).toBeUndefined()
           },
@@ -92,7 +97,10 @@ describe("tool.webfetch", () => {
         await Instance.provide({
           directory: projectRoot,
           fn: async () => {
-            const result = await exec({ url: new URL("/file.txt", url).toString(), format: "text" })
+            const webfetch = await initTool()
+            const result = await Effect.runPromise(
+              webfetch.execute({ url: new URL("/file.txt", url).toString(), format: "text" }, ctx),
+            )
             expect(result.output).toBe("hello from webfetch")
             expect(result.attachments).toBeUndefined()
           },