agent-neckbeard 0.0.1 → 0.0.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/README.md +8 -0
- package/dist/index.js +37 -11
- package/package.json +19 -8
package/README.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import * as esbuild from "esbuild";
|
|
3
|
-
import { Sandbox } from "e2b";
|
|
4
2
|
import { fileURLToPath } from "url";
|
|
3
|
+
var getEsbuild = () => import("esbuild");
|
|
4
|
+
var getE2b = () => import("e2b");
|
|
5
5
|
function getCallerFile() {
|
|
6
6
|
const stack = new Error().stack?.split("\n") ?? [];
|
|
7
7
|
for (const line of stack.slice(2)) {
|
|
@@ -9,7 +9,7 @@ function getCallerFile() {
|
|
|
9
9
|
if (match) {
|
|
10
10
|
let file = match[1];
|
|
11
11
|
if (file.startsWith("file://")) file = fileURLToPath(file);
|
|
12
|
-
if (!file.includes("node:") && !file.includes("agent-neckbeard")) return file;
|
|
12
|
+
if (!file.includes("node:") && !file.includes("node_modules/agent-neckbeard") && !file.includes("agent-neckbeard/dist")) return file;
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
throw new Error("Could not determine source file");
|
|
@@ -37,6 +37,8 @@ var Agent = class {
|
|
|
37
37
|
}
|
|
38
38
|
async deploy() {
|
|
39
39
|
if (this._sandboxId) return;
|
|
40
|
+
const esbuild = await getEsbuild();
|
|
41
|
+
const { Sandbox } = await getE2b();
|
|
40
42
|
const result = await esbuild.build({
|
|
41
43
|
entryPoints: [this._sourceFile],
|
|
42
44
|
bundle: true,
|
|
@@ -45,15 +47,38 @@ var Agent = class {
|
|
|
45
47
|
format: "esm",
|
|
46
48
|
write: false,
|
|
47
49
|
minify: true,
|
|
48
|
-
keepNames: true
|
|
50
|
+
keepNames: true,
|
|
51
|
+
plugins: [{
|
|
52
|
+
name: "agent-neckbeard-shim",
|
|
53
|
+
setup(build) {
|
|
54
|
+
build.onResolve({ filter: /^agent-neckbeard$/ }, () => ({
|
|
55
|
+
path: "agent-neckbeard",
|
|
56
|
+
namespace: "agent-shim"
|
|
57
|
+
}));
|
|
58
|
+
build.onLoad({ filter: /.*/, namespace: "agent-shim" }, () => ({
|
|
59
|
+
contents: `
|
|
60
|
+
export class Agent {
|
|
61
|
+
constructor(config) {
|
|
62
|
+
this.id = config.id;
|
|
63
|
+
this.inputSchema = config.inputSchema;
|
|
64
|
+
this.outputSchema = config.outputSchema;
|
|
65
|
+
this.maxDuration = config.maxDuration ?? 300;
|
|
66
|
+
this._run = config.run;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
`,
|
|
70
|
+
loader: "js"
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
}]
|
|
49
74
|
});
|
|
50
75
|
const runnerCode = `
|
|
51
76
|
import { readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
52
77
|
|
|
53
|
-
mkdirSync('/input', { recursive: true });
|
|
54
|
-
mkdirSync('/output', { recursive: true });
|
|
78
|
+
mkdirSync('/home/user/input', { recursive: true });
|
|
79
|
+
mkdirSync('/home/user/output', { recursive: true });
|
|
55
80
|
|
|
56
|
-
const { input, executionId } = JSON.parse(readFileSync('/input/task.json', 'utf-8'));
|
|
81
|
+
const { input, executionId } = JSON.parse(readFileSync('/home/user/input/task.json', 'utf-8'));
|
|
57
82
|
|
|
58
83
|
const ctx = {
|
|
59
84
|
executionId,
|
|
@@ -74,9 +99,9 @@ try {
|
|
|
74
99
|
const validated = agent.inputSchema.parse(input);
|
|
75
100
|
const output = await agent._run(validated, ctx);
|
|
76
101
|
const validatedOutput = agent.outputSchema.parse(output);
|
|
77
|
-
writeFileSync('/output/result.json', JSON.stringify({ success: true, output: validatedOutput }));
|
|
102
|
+
writeFileSync('/home/user/output/result.json', JSON.stringify({ success: true, output: validatedOutput }));
|
|
78
103
|
} catch (error) {
|
|
79
|
-
writeFileSync('/output/result.json', JSON.stringify({ success: false, error: { message: error.message, stack: error.stack } }));
|
|
104
|
+
writeFileSync('/home/user/output/result.json', JSON.stringify({ success: false, error: { message: error.message, stack: error.stack } }));
|
|
80
105
|
}
|
|
81
106
|
`;
|
|
82
107
|
const sandbox = await Sandbox.create("base", {
|
|
@@ -90,17 +115,18 @@ try {
|
|
|
90
115
|
if (!this._sandboxId) {
|
|
91
116
|
throw new Error("Agent not deployed. Call agent.deploy() first or pass sandboxId to constructor.");
|
|
92
117
|
}
|
|
118
|
+
const { Sandbox } = await getE2b();
|
|
93
119
|
const validatedInput = this.inputSchema.parse(input);
|
|
94
120
|
const executionId = `exec_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
95
121
|
const sandbox = await Sandbox.connect(this._sandboxId, {
|
|
96
122
|
apiKey: process.env.E2B_API_KEY
|
|
97
123
|
});
|
|
98
|
-
await sandbox.files.write("/input/task.json", JSON.stringify({ input: validatedInput, executionId }));
|
|
124
|
+
await sandbox.files.write("/home/user/input/task.json", JSON.stringify({ input: validatedInput, executionId }));
|
|
99
125
|
const result = await sandbox.commands.run("node /home/user/runner.mjs", {
|
|
100
126
|
timeoutMs: this.maxDuration * 1e3
|
|
101
127
|
});
|
|
102
128
|
if (result.exitCode !== 0) throw new Error(`Agent failed: ${result.stderr}`);
|
|
103
|
-
const output = JSON.parse(await sandbox.files.read("/output/result.json"));
|
|
129
|
+
const output = JSON.parse(await sandbox.files.read("/home/user/output/result.json"));
|
|
104
130
|
if (!output.success) {
|
|
105
131
|
const err = new Error(output.error.message);
|
|
106
132
|
err.stack = output.error.stack;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-neckbeard",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Deploy AI agents to E2B sandboxes",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
},
|
|
14
14
|
"main": "./dist/index.js",
|
|
15
15
|
"types": "./dist/index.d.ts",
|
|
16
|
-
"files": [
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
17
19
|
"engines": {
|
|
18
20
|
"node": ">=20.0.0"
|
|
19
21
|
},
|
|
@@ -23,21 +25,30 @@
|
|
|
23
25
|
"typecheck": "tsc --noEmit"
|
|
24
26
|
},
|
|
25
27
|
"dependencies": {
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
+
"e2b": "^1.0.0",
|
|
29
|
+
"esbuild": "^0.24.0"
|
|
28
30
|
},
|
|
29
31
|
"peerDependencies": {
|
|
30
32
|
"zod": "^3.0.0"
|
|
31
33
|
},
|
|
32
34
|
"peerDependenciesMeta": {
|
|
33
|
-
"zod": {
|
|
35
|
+
"zod": {
|
|
36
|
+
"optional": true
|
|
37
|
+
}
|
|
34
38
|
},
|
|
35
39
|
"devDependencies": {
|
|
36
|
-
"
|
|
40
|
+
"@types/node": "^22.0.0",
|
|
37
41
|
"tsup": "^8.3.0",
|
|
38
|
-
"
|
|
42
|
+
"typescript": "^5.6.0"
|
|
39
43
|
},
|
|
40
|
-
"keywords": [
|
|
44
|
+
"keywords": [
|
|
45
|
+
"ai",
|
|
46
|
+
"agent",
|
|
47
|
+
"deploy",
|
|
48
|
+
"e2b",
|
|
49
|
+
"sandbox",
|
|
50
|
+
"claude"
|
|
51
|
+
],
|
|
41
52
|
"license": "MIT",
|
|
42
53
|
"author": "zacwellmer",
|
|
43
54
|
"repository": {
|