saadpie commited on
Commit
632108b
·
verified ·
1 Parent(s): e3625a0

Create api/index.ts

Browse files
Files changed (1) hide show
  1. api/index.ts +153 -0
api/index.ts ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import express from "express";
2
+ import cors from "cors";
3
+ import dotenv from "dotenv";
4
+ import fetch from "node-fetch";
5
+ import { exec } from "child_process";
6
+ import { promisify } from "util";
7
+ import fs from "fs";
8
+
9
+ const execPromise = promisify(exec);
10
+ dotenv.config();
11
+
12
+ const app = express();
13
+ app.use(cors());
14
+ app.use(express.json());
15
+
16
+ const CONFIG = {
17
+ groq: {
18
+ apiKey: process.env.GROQ_API_KEY || "",
19
+ model: process.env.MODEL_ID || "openai/gpt-oss-120b"
20
+ }
21
+ };
22
+
23
+ const OPENCLAW_SYSTEM_PROMPT = `
24
+ You are OpenClaw, a self-evolving autonomous agent with FULL SHELL ACCESS.
25
+ Your goal is to fulfill user requests by planning, installing necessary skills, and executing tasks INTERNALLY.
26
+
27
+ CAPABILITIES:
28
+ 1. DYNAMIC SKILL INSTALLATION: Use 'execute_shell' to install any tool (ffmpeg, yt-dlp, npm packages, python libs).
29
+ 2. INTERNAL EXECUTION: You are running in a persistent cloud container. You execute commands yourself.
30
+ 3. CODE GENERATION: Write and execute Node.js, Python, or Shell scripts to perform complex operations.
31
+
32
+ OPERATIONAL GUIDELINES:
33
+ - You have permission to manage files and execute commands to fulfill the mission.
34
+ - If a tool is missing, INSTALL IT.
35
+ - For multi-step tasks, provide your full plan first, then execute step-by-step.
36
+ `;
37
+
38
+ const tools = [
39
+ {
40
+ name: "execute_shell",
41
+ description: "Executes a shell command in the cloud environment.",
42
+ parameters: {
43
+ type: "object",
44
+ properties: {
45
+ command: { type: "string", description: "The bash/shell command to execute" }
46
+ },
47
+ required: ["command"]
48
+ }
49
+ },
50
+ {
51
+ name: "read_write_file",
52
+ description: "Read or write content to a file in the workspace.",
53
+ parameters: {
54
+ type: "object",
55
+ properties: {
56
+ path: { type: "string", description: "File path" },
57
+ content: { type: "string", description: "Content to write (if writing)" },
58
+ action: { type: "string", enum: ["read", "write"] }
59
+ },
60
+ required: ["path", "action"]
61
+ }
62
+ }
63
+ ];
64
+
65
+ // Self-Executing Agent Loop
66
+ app.post("/api/agent", async (req, res) => {
67
+ const { message, history = [] } = req.body;
68
+ let currentHistory = [...history];
69
+ let currentMessage = message;
70
+ let finalResponse = { content: "", actions: [] as any[] };
71
+
72
+ try {
73
+ // Run up to 10 iterations to prevent infinite loops
74
+ for (let i = 0; i < 10; i++) {
75
+ const response = await fetch("https://api.groq.com/openai/v1/chat/completions", {
76
+ method: "POST",
77
+ headers: {
78
+ "Authorization": \`Bearer \${CONFIG.groq.apiKey}\`,
79
+ "Content-Type": "application/json"
80
+ },
81
+ body: JSON.stringify({
82
+ model: CONFIG.groq.model,
83
+ messages: [
84
+ { role: "system", content: OPENCLAW_SYSTEM_PROMPT },
85
+ ...currentHistory,
86
+ { role: "user", content: currentMessage }
87
+ ],
88
+ tools: tools.map(t => ({ type: "function", function: t })),
89
+ tool_choice: "auto",
90
+ temperature: 0.5
91
+ })
92
+ });
93
+
94
+ const data: any = await response.json();
95
+ if (!response.ok) throw new Error(data.error?.message || "Groq Error");
96
+
97
+ const assistantMessage = data.choices[0].message;
98
+ currentHistory.push(assistantMessage);
99
+
100
+ if (assistantMessage.content) {
101
+ finalResponse.content += assistantMessage.content + "\n";
102
+ }
103
+
104
+ if (!assistantMessage.tool_calls) {
105
+ break; // Task finished
106
+ }
107
+
108
+ // EXECUTE TOOLS INTERNALLY
109
+ for (const call of assistantMessage.tool_calls) {
110
+ const { name, arguments: argsJson } = call.function;
111
+ const args = JSON.parse(argsJson);
112
+ let output = "";
113
+
114
+ try {
115
+ if (name === "execute_shell") {
116
+ const { stdout, stderr } = await execPromise(args.command);
117
+ output = stdout || stderr || "Success";
118
+ } else if (name === "read_write_file") {
119
+ if (args.action === "write") {
120
+ fs.writeFileSync(args.path, args.content);
121
+ output = \`Successfully wrote to \${args.path}\`;
122
+ } else {
123
+ output = fs.readFileSync(args.path, "utf8");
124
+ }
125
+ }
126
+ } catch (err: any) {
127
+ output = \`Error: \${err.message}\`;
128
+ }
129
+
130
+ currentHistory.push({
131
+ tool_call_id: call.id,
132
+ role: "tool",
133
+ name: name,
134
+ content: output
135
+ });
136
+
137
+ finalResponse.actions.push({ name, args, output });
138
+ }
139
+
140
+ currentMessage = "Continue based on the tool results.";
141
+ }
142
+
143
+ res.json(finalResponse);
144
+
145
+ } catch (error: any) {
146
+ res.status(500).json({ error: error.message });
147
+ }
148
+ });
149
+
150
+ app.get("/", (req, res) => res.send("OpenClaw Autonomous Cloud Server is running."));
151
+
152
+ const PORT = process.env.PORT || 3000;
153
+ app.listen(PORT, () => console.log(\`Server running on port \${PORT}\`));