likhonsheikh commited on
Commit
ed89324
·
verified ·
1 Parent(s): 313ad68

Create agent.js

Browse files
Files changed (1) hide show
  1. agent.js +76 -0
agent.js ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { spawn } from "child_process";
2
+ import fs from "fs";
3
+
4
+ let toolSpec;
5
+ export function listTools() {
6
+ if (!toolSpec) {
7
+ toolSpec = JSON.parse(fs.readFileSync("tools.json", "utf-8"));
8
+ }
9
+ return toolSpec;
10
+ }
11
+
12
+ /**
13
+ * Stream a child process over SSE.
14
+ * send(eventType, payload) writes to the SSE connection.
15
+ */
16
+ function streamProcess(cmd, args, options, send) {
17
+ const child = spawn(cmd, args, { shell: false, ...options });
18
+
19
+ child.stdout.on("data", (chunk) => {
20
+ send("output", { data: chunk.toString() });
21
+ });
22
+
23
+ child.stderr.on("data", (chunk) => {
24
+ send("error", { data: chunk.toString() });
25
+ });
26
+
27
+ child.on("close", (code) => {
28
+ send("done", { code });
29
+ });
30
+
31
+ child.on("error", (err) => {
32
+ send("error", { data: String(err) });
33
+ send("done", { code: -1 });
34
+ });
35
+
36
+ return child;
37
+ }
38
+
39
+ /**
40
+ * Execute a tool call and stream results.
41
+ * tool: "shell" | "python"
42
+ * args: { command } | { code }
43
+ */
44
+ export function executeTool(tool, args, send) {
45
+ if (tool === "shell") {
46
+ if (!args?.command || typeof args.command !== "string") {
47
+ send("error", { data: "Missing 'command' string." });
48
+ return send("done", { code: 2 });
49
+ }
50
+ // Use /bin/bash -lc to enable pipes, redirects, env, etc.
51
+ return streamProcess("/bin/bash", ["-lc", args.command], {}, send);
52
+ }
53
+
54
+ if (tool === "python") {
55
+ if (!args?.code || typeof args.code !== "string") {
56
+ send("error", { data: "Missing 'code' string." });
57
+ return send("done", { code: 2 });
58
+ }
59
+ // Run python inline, escape newlines safely by passing as stdin
60
+ const child = spawn("python3", ["-"], { stdio: ["pipe", "pipe", "pipe"] });
61
+ child.stdin.write(args.code);
62
+ child.stdin.end();
63
+
64
+ child.stdout.on("data", (chunk) => send("output", { data: chunk.toString() }));
65
+ child.stderr.on("data", (chunk) => send("error", { data: chunk.toString() }));
66
+ child.on("close", (code) => send("done", { code }));
67
+ child.on("error", (err) => {
68
+ send("error", { data: String(err) });
69
+ send("done", { code: -1 });
70
+ });
71
+ return child;
72
+ }
73
+
74
+ send("error", { data: `Unknown tool '${tool}'.` });
75
+ send("done", { code: 2 });
76
+ }