Browse Source

fix bash tool getting stuck on interactive commands

Dax Raad 6 months ago
parent
commit
21c52fd5cb
2 changed files with 15 additions and 13 deletions
  1. 2 2
      packages/opencode/src/session/index.ts
  2. 13 11
      packages/opencode/src/tool/bash.ts

+ 2 - 2
packages/opencode/src/session/index.ts

@@ -737,7 +737,7 @@ export namespace Session {
           )
           const result = await item.execute(args, {
             sessionID: input.sessionID,
-            abort: abort.signal,
+            abort: options.abortSignal!,
             messageID: assistantMsg.id,
             callID: options.toolCallId,
             metadata: async (val) => {
@@ -779,7 +779,7 @@ export namespace Session {
     }
 
     for (const [key, item] of Object.entries(await MCP.tools())) {
-      if (mode.tools[key] === false) continue
+      if (enabledTools[key] === false) continue
       const execute = item.execute
       if (!execute) continue
       item.execute = async (args, opts) => {

+ 13 - 11
packages/opencode/src/tool/bash.ts

@@ -1,4 +1,6 @@
 import { z } from "zod"
+import { spawn } from "child_process"
+import { text } from "stream/consumers"
 import { Tool } from "./tool"
 import DESCRIPTION from "./bash.txt"
 import { App } from "../app/app"
@@ -10,7 +12,7 @@ import { Log } from "../util/log"
 import { Wildcard } from "../util/wildcard"
 import { $ } from "bun"
 
-const MAX_OUTPUT_LENGTH = 30000
+// const MAX_OUTPUT_LENGTH = 30000
 const DEFAULT_TIMEOUT = 1 * 60 * 1000
 const MAX_TIMEOUT = 10 * 60 * 1000
 
@@ -116,19 +118,19 @@ export const BashTool = Tool.define("bash", {
       })
     }
 
-    const process = Bun.spawn({
-      cmd: ["bash", "-c", params.command],
+    const process = spawn("bash", ["-c", params.command], {
+      stdio: "pipe",
       cwd: app.path.cwd,
-      maxBuffer: MAX_OUTPUT_LENGTH,
       signal: ctx.abort,
-      timeout: timeout,
-      stdin: "pipe",
-      stdout: "pipe",
-      stderr: "pipe",
+      timeout,
     })
-    await process.exited
-    const stdout = await new Response(process.stdout).text()
-    const stderr = await new Response(process.stderr).text()
+    await new Promise<void>((resolve) => {
+      process.on("close", () => {
+        resolve()
+      })
+    })
+    const stdout = await text(process.stdout)
+    const stderr = await text(process.stderr)
 
     return {
       title: params.command,