Bladeren bron

Revert "fix(core): bust external plugin import cache"

This reverts commit afe3ebbc35731131893b98893e8fadfbcf4562dd.
Dax Raad 1 maand geleden
bovenliggende
commit
f66c829231
2 gewijzigde bestanden met toevoegingen van 2 en 90 verwijderingen
  1. 2 17
      packages/core/src/config/plugin/external.ts
  2. 0 73
      packages/core/test/config/plugin.test.ts

+ 2 - 17
packages/core/src/config/plugin/external.ts

@@ -3,7 +3,6 @@ export * as ConfigExternalPlugin from "./external"
 import type { Plugin as EffectPlugin } from "@opencode-ai/plugin/v2/effect"
 import type { Plugin as PromisePlugin } from "@opencode-ai/plugin/v2/promise"
 import { Effect, Schema, Stream } from "effect"
-import { createRequire } from "node:module"
 import path from "path"
 import { fileURLToPath, pathToFileURL } from "url"
 import { Config } from "../../config"
@@ -36,9 +35,6 @@ const PluginPackage = Schema.Struct({
   module: Schema.optional(Schema.String),
 })
 
-let importGeneration = 0
-const moduleCache = createRequire(import.meta.url).cache
-
 export const Plugin = define({
   id: "config-plugin",
   effect: Effect.fn(function* (ctx) {
@@ -110,7 +106,7 @@ export const Plugin = define({
             : (yield* npm.add(ref.package)).entrypoint
           if (!entrypoint) return
           yield* Effect.log({ msg: "loading plugin", id: ref.package, entrypoint })
-          const mod = yield* Effect.promise(() => import(cacheBust(entrypoint)))
+          const mod = yield* Effect.promise(() => import(entrypoint))
           const value = (yield* Schema.decodeUnknownEffect(PluginModule)(mod)).default
           const plugin = "effect" in value ? value : PluginPromise.fromPromise(value)
           return {
@@ -118,11 +114,7 @@ export const Plugin = define({
             effect: (host: Parameters<typeof plugin.effect>[0]) =>
               plugin.effect({ ...host, options: ref.options ?? {} }),
           }
-        }).pipe(
-          Effect.catchCause((cause) =>
-            Effect.logError("failed to load plugin", { package: ref.package, cause }).pipe(Effect.as(undefined)),
-          ),
-        ),
+        }).pipe(Effect.catchCause(() => Effect.succeed(undefined))),
       ).pipe(Effect.map((plugins) => plugins.filter((plugin) => plugin !== undefined)))
     })
     const reconcile = Effect.fn("ConfigExternalPlugin.reconcile")(function* () {
@@ -145,13 +137,6 @@ export const Plugin = define({
   }),
 })
 
-function cacheBust(entrypoint: string) {
-  const url = path.isAbsolute(entrypoint) ? pathToFileURL(entrypoint) : new URL(entrypoint)
-  if (url.protocol === "file:") delete moduleCache[fileURLToPath(url)]
-  url.searchParams.set("opencode-reload", String(++importGeneration))
-  return url.href
-}
-
 const resolvePackageEntrypoint = Effect.fnUntraced(function* (fs: FSUtil.Interface, directory: string) {
   const pkg = yield* fs.readJson(path.join(directory, "package.json")).pipe(
     Effect.flatMap(Schema.decodeUnknownEffect(PluginPackage)),

+ 0 - 73
packages/core/test/config/plugin.test.ts

@@ -1,19 +1,15 @@
-import fs from "fs/promises"
 import path from "path"
 import { describe, expect } from "bun:test"
-import { Config as ConfigSchema } from "@opencode-ai/schema/config"
 import { Effect, Schema } from "effect"
 import { AgentV2 } from "@opencode-ai/core/agent"
 import { Config } from "@opencode-ai/core/config"
 import { ConfigExternalPlugin } from "@opencode-ai/core/config/plugin/external"
-import { EventV2 } from "@opencode-ai/core/event"
 import { FSUtil } from "@opencode-ai/core/fs-util"
 import { Location } from "@opencode-ai/core/location"
 import { Npm } from "@opencode-ai/core/npm"
 import { PluginV2 } from "@opencode-ai/core/plugin"
 import { PluginHost } from "@opencode-ai/core/plugin/host"
 import { AbsolutePath } from "@opencode-ai/core/schema"
-import { tmpdir } from "../fixture/tmpdir"
 import { testEffect } from "../lib/effect"
 import { PluginTestLayer } from "../plugin/fixture"
 
@@ -244,49 +240,6 @@ describe("ConfigExternalPlugin", () => {
       })
     }),
   )
-
-  it.live("reloads changed plugin source from the same entrypoint", () =>
-    Effect.acquireRelease(
-      Effect.promise(() => tmpdir()),
-      (tmp) => Effect.promise(() => tmp[Symbol.asyncDispose]()),
-    ).pipe(
-      Effect.flatMap((tmp) =>
-        Effect.gen(function* () {
-          const plugins = yield* PluginV2.Service
-          const agents = yield* AgentV2.Service
-          const events = yield* EventV2.Service
-          const fsUtil = yield* FSUtil.Service
-          const location = yield* Location.Service
-          const npm = yield* Npm.Service
-          const host = yield* PluginHost.make(plugins)
-          const plugin = path.join(tmp.path, "plugin.ts")
-          const config = Config.Service.of({
-            entries: () =>
-              Effect.succeed([
-                new Config.Document({
-                  type: "document",
-                  info: decode({ plugins: [plugin] }),
-                }),
-              ]),
-          })
-
-          yield* Effect.promise(() => fs.writeFile(plugin, pluginSource("First source")))
-          yield* ConfigExternalPlugin.Plugin.effect(host).pipe(
-            Effect.provideService(PluginV2.Service, plugins),
-            Effect.provideService(FSUtil.Service, fsUtil),
-            Effect.provideService(Location.Service, location),
-            Effect.provideService(Npm.Service, npm),
-            Effect.provideService(Config.Service, config),
-          )
-          expect((yield* waitForAgent(agents, "hot-reload"))?.description).toBe("First source")
-
-          yield* Effect.promise(() => fs.writeFile(plugin, pluginSource("Second source")))
-          yield* events.publish(ConfigSchema.Event.Updated, {})
-          expect(yield* waitForAgentDescription(agents, "hot-reload", "Second source")).toBe(true)
-        }),
-      ),
-    ),
-  )
 })
 
 const waitForAgent = Effect.fnUntraced(function* (agents: AgentV2.Interface, id: string) {
@@ -297,29 +250,3 @@ const waitForAgent = Effect.fnUntraced(function* (agents: AgentV2.Interface, id:
   }
   return yield* Effect.die(`Timed out waiting for agent ${id}`)
 })
-
-const waitForAgentDescription = Effect.fnUntraced(function* (
-  agents: AgentV2.Interface,
-  id: string,
-  description: string,
-) {
-  for (let attempt = 0; attempt < 100; attempt++) {
-    if ((yield* agents.get(AgentV2.ID.make(id)))?.description === description) return true
-    yield* Effect.sleep("10 millis")
-  }
-  return false
-})
-
-function pluginSource(description: string) {
-  return `export default {
-  id: "source-hot-reload",
-  setup: async (ctx) => {
-    await ctx.agent.transform((agents) => {
-      agents.update("hot-reload", (agent) => {
-        agent.description = ${JSON.stringify(description)}
-        agent.mode = "subagent"
-      })
-    })
-  },
-}`
-}