@calamity-inc/slave 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +32 -20
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { execFileSync, spawnSync } from "node:child_process";
|
|
4
|
+
import { randomInt } from "node:crypto";
|
|
4
5
|
import fs from "node:fs";
|
|
5
6
|
import path from "node:path";
|
|
6
7
|
import { createInterface } from "node:readline/promises";
|
|
@@ -109,17 +110,12 @@ const writeFileFromModel = (filePath, data, usesCRLF) => {
|
|
|
109
110
|
fs.writeFileSync(filePath, usesCRLF ? normalized.replaceAll("\n", "\r\n") : normalized, "utf8");
|
|
110
111
|
};
|
|
111
112
|
|
|
112
|
-
let
|
|
113
|
+
let sandbox_name;
|
|
113
114
|
const ensureSandbox = () => {
|
|
114
|
-
if (!
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
119
|
-
catch (e) {
|
|
120
|
-
// container may already exist if it was not cleaned up previously. this is okay-ish.
|
|
121
|
-
}
|
|
122
|
-
used_docker = true;
|
|
115
|
+
if (!sandbox_name) {
|
|
116
|
+
sandbox_name = "slave-sandbox-" + Array.from({ length: 10 }, () => "abcdefghijklmnopqrstuvwxyz0123456789"[randomInt(36)]).join("");
|
|
117
|
+
// `docker pull ghcr.io/calamity-inc/slave-sandbox` is not needed to get the image, but would be needed to update it.
|
|
118
|
+
execFileSync("docker", ["run", "-d", "--name", sandbox_name, "ghcr.io/calamity-inc/slave-sandbox", "sleep", "infinity"], { encoding: "utf8" });
|
|
123
119
|
}
|
|
124
120
|
};
|
|
125
121
|
|
|
@@ -162,9 +158,14 @@ const functions = {
|
|
|
162
158
|
.filter(file => !isOutOfReach(file));
|
|
163
159
|
const res = [];
|
|
164
160
|
for (const file of files) {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
161
|
+
try {
|
|
162
|
+
const matches = readFileForModel(file).split(substring).length - 1;
|
|
163
|
+
if (matches) {
|
|
164
|
+
res.push(`${file} has ${matches} match${matches == 1 ? "" : "es"}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch (e) {
|
|
168
|
+
// file might be busy, skip it
|
|
168
169
|
}
|
|
169
170
|
}
|
|
170
171
|
return res.join("\n");
|
|
@@ -177,7 +178,11 @@ const functions = {
|
|
|
177
178
|
if (!fs.existsSync(path) || !fs.statSync(path).isFile()) {
|
|
178
179
|
return "No such file";
|
|
179
180
|
}
|
|
180
|
-
|
|
181
|
+
const cont = readFileForModel(path);
|
|
182
|
+
if (cont.length > 10485760) {
|
|
183
|
+
return "File is over 10485760 characters long";
|
|
184
|
+
}
|
|
185
|
+
return cont;
|
|
181
186
|
},
|
|
182
187
|
writeFile: ({ path, data }) => {
|
|
183
188
|
path = fixPath(path, "write");
|
|
@@ -204,7 +209,11 @@ const functions = {
|
|
|
204
209
|
},
|
|
205
210
|
sandboxExec: ({ command, args }) => {
|
|
206
211
|
ensureSandbox();
|
|
207
|
-
|
|
212
|
+
args ??= [];
|
|
213
|
+
if (typeof args == "string") {
|
|
214
|
+
args = JSON.parse(args);
|
|
215
|
+
}
|
|
216
|
+
const result = spawnSync("docker", [ "exec", sandbox_name, command, ...args ], { encoding: "utf8" });
|
|
208
217
|
const output = (result.stdout ?? "") + (result.stderr ?? "");
|
|
209
218
|
if (result.error) {
|
|
210
219
|
return (output || result.error.message).trimEnd();
|
|
@@ -224,7 +233,7 @@ const functions = {
|
|
|
224
233
|
}
|
|
225
234
|
ensureSandbox();
|
|
226
235
|
try {
|
|
227
|
-
execFileSync("docker", ["cp", "-L", hostPath,
|
|
236
|
+
execFileSync("docker", ["cp", "-L", hostPath, `${sandbox_name}:${sbxPath}`], { encoding: "utf8" });
|
|
228
237
|
return "OK";
|
|
229
238
|
}
|
|
230
239
|
catch (e) {
|
|
@@ -240,7 +249,7 @@ const functions = {
|
|
|
240
249
|
return "Host path must point to a file";
|
|
241
250
|
}
|
|
242
251
|
ensureSandbox();
|
|
243
|
-
execFileSync("docker", ["cp", "-L",
|
|
252
|
+
execFileSync("docker", ["cp", "-L", `${sandbox_name}:${sbxPath}`, hostPath], { encoding: "utf8" });
|
|
244
253
|
return "OK";
|
|
245
254
|
},
|
|
246
255
|
/*system: ({ command }) => {
|
|
@@ -605,9 +614,11 @@ const overrides = [profileToString(profile)];
|
|
|
605
614
|
state.providerStates[profile.provider] ??= {};
|
|
606
615
|
if (options.continue || options.cont) {
|
|
607
616
|
previous_provider_state = state.providerStates[profile.provider].previous;
|
|
617
|
+
sandbox_name = state.providerStates[profile.provider].sandbox_name;
|
|
608
618
|
}
|
|
609
619
|
else if (options.amend) {
|
|
610
620
|
previous_provider_state = state.providerStates[profile.provider].previous_previous;
|
|
621
|
+
sandbox_name = state.providerStates[profile.provider].sandbox_name;
|
|
611
622
|
}
|
|
612
623
|
const filesystemEnabled = options.fs !== false && !options.nofs;
|
|
613
624
|
initTools(filesystemEnabled, options.sandbox, options.web);
|
|
@@ -656,11 +667,12 @@ else {
|
|
|
656
667
|
}
|
|
657
668
|
state.providerStates[profile.provider].previous_previous = previous_provider_state;
|
|
658
669
|
state.providerStates[profile.provider].previous = response.state;
|
|
670
|
+
if (state.providerStates[profile.provider].sandbox_name && state.providerStates[profile.provider].sandbox_name != sandbox_name) {
|
|
671
|
+
execFileSync("docker", ["rm", "-f", state.providerStates[profile.provider].sandbox_name], { encoding: "utf8" });
|
|
672
|
+
}
|
|
673
|
+
state.providerStates[profile.provider].sandbox_name = sandbox_name;
|
|
659
674
|
saveState();
|
|
660
675
|
if (response.used_tools) {
|
|
661
|
-
if (used_docker) {
|
|
662
|
-
execFileSync("docker", ["rm", "-f", "slave-sandbox"], { encoding: "utf8" });
|
|
663
|
-
}
|
|
664
676
|
logWriteBoth("");
|
|
665
677
|
}
|
|
666
678
|
console.log(markdownToConsoleText(response.output_text) + "\n");
|