Просмотр исходного кода

fix(bash): memory leak - release parsed syntax trees (#24861)

Co-authored-by: jiwenshang <jiwenshang@xiaohongshu.com>
Luke Parker 4 месяцев назад
Родитель
Сommit
d4bf70be06
1 измененных файлов с 12 добавлено и 5 удалено
  1. 12 5
      packages/opencode/src/tool/bash.ts

+ 12 - 5
packages/opencode/src/tool/bash.ts

@@ -252,7 +252,7 @@ function tail(text: string, maxLines: number, maxBytes: number) {
 const parse = Effect.fn("BashTool.parse")(function* (command: string, ps: boolean) {
 const parse = Effect.fn("BashTool.parse")(function* (command: string, ps: boolean) {
   const tree = yield* Effect.promise(() => parser().then((p) => (ps ? p.ps : p.bash).parse(command)))
   const tree = yield* Effect.promise(() => parser().then((p) => (ps ? p.ps : p.bash).parse(command)))
   if (!tree) throw new Error("Failed to parse command")
   if (!tree) throw new Error("Failed to parse command")
-  return tree.rootNode
+  return tree
 })
 })
 
 
 const ask = Effect.fn("BashTool.ask")(function* (ctx: Tool.Context, scan: Scan) {
 const ask = Effect.fn("BashTool.ask")(function* (ctx: Tool.Context, scan: Scan) {
@@ -596,10 +596,17 @@ export const BashTool = Tool.define(
               }
               }
               const timeout = params.timeout ?? DEFAULT_TIMEOUT
               const timeout = params.timeout ?? DEFAULT_TIMEOUT
               const ps = Shell.ps(shell)
               const ps = Shell.ps(shell)
-              const root = yield* parse(params.command, ps)
-              const scan = yield* collect(root, cwd, ps, shell)
-              if (!Instance.containsPath(cwd)) scan.dirs.add(cwd)
-              yield* ask(ctx, scan)
+              yield* Effect.scoped(
+                Effect.gen(function* () {
+                  const tree = yield* Effect.acquireRelease(
+                    parse(params.command, ps),
+                    (tree) => Effect.sync(() => tree.delete()),
+                  )
+                  const scan = yield* collect(tree.rootNode, cwd, ps, shell)
+                  if (!Instance.containsPath(cwd)) scan.dirs.add(cwd)
+                  yield* ask(ctx, scan)
+                }),
+              )
 
 
               return yield* run(
               return yield* run(
                 {
                 {