Spaces:
Runtime error
Runtime error
import { spawn } from "child_process"; | |
import fs from "fs"; | |
let toolSpec; | |
export function listTools() { | |
if (!toolSpec) { | |
toolSpec = JSON.parse(fs.readFileSync("tools.json", "utf-8")); | |
} | |
return toolSpec; | |
} | |
/** | |
* Stream a child process over SSE. | |
* send(eventType, payload) writes to the SSE connection. | |
*/ | |
function streamProcess(cmd, args, options, send) { | |
const child = spawn(cmd, args, { shell: false, ...options }); | |
child.stdout.on("data", (chunk) => { | |
send("output", { data: chunk.toString() }); | |
}); | |
child.stderr.on("data", (chunk) => { | |
send("error", { data: chunk.toString() }); | |
}); | |
child.on("close", (code) => { | |
send("done", { code }); | |
}); | |
child.on("error", (err) => { | |
send("error", { data: String(err) }); | |
send("done", { code: -1 }); | |
}); | |
return child; | |
} | |
/** | |
* Execute a tool call and stream results. | |
* tool: "shell" | "python" | |
* args: { command } | { code } | |
*/ | |
export function executeTool(tool, args, send) { | |
if (tool === "shell") { | |
if (!args?.command || typeof args.command !== "string") { | |
send("error", { data: "Missing 'command' string." }); | |
return send("done", { code: 2 }); | |
} | |
// Use /bin/bash -lc to enable pipes, redirects, env, etc. | |
return streamProcess("/bin/bash", ["-lc", args.command], {}, send); | |
} | |
if (tool === "python") { | |
if (!args?.code || typeof args.code !== "string") { | |
send("error", { data: "Missing 'code' string." }); | |
return send("done", { code: 2 }); | |
} | |
// Run python inline, escape newlines safely by passing as stdin | |
const child = spawn("python3", ["-"], { stdio: ["pipe", "pipe", "pipe"] }); | |
child.stdin.write(args.code); | |
child.stdin.end(); | |
child.stdout.on("data", (chunk) => send("output", { data: chunk.toString() })); | |
child.stderr.on("data", (chunk) => send("error", { data: chunk.toString() })); | |
child.on("close", (code) => send("done", { code })); | |
child.on("error", (err) => { | |
send("error", { data: String(err) }); | |
send("done", { code: -1 }); | |
}); | |
return child; | |
} | |
send("error", { data: `Unknown tool '${tool}'.` }); | |
send("done", { code: 2 }); | |
} |