lua-cli 1.3.2-alpha.0 → 1.3.2-alpha.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/dist/commands/compile.js +227 -165
- package/dist/commands/dev.js +117 -114
- package/dist/commands/test.js +122 -130
- package/dist/services/api.d.ts +4 -4
- package/dist/services/api.js +8 -4
- package/dist/skill.d.ts +16 -1
- package/dist/skill.js +49 -0
- package/dist/types/index.d.ts +3 -3
- package/dist/user-data-api.d.ts +1 -0
- package/dist/user-data-api.js +9 -4
- package/dist/utils/files.js +33 -5
- package/dist/utils/sandbox.d.ts +96 -0
- package/dist/utils/sandbox.js +161 -0
- package/dist/web/app.css +274 -43
- package/dist/web/app.js +13 -13
- package/dist/web/tools-page.css +70 -53
- package/package.json +1 -1
- package/template/lua.skill.yaml +16 -0
- package/template/package-lock.json +9 -1
- package/template/package.json +3 -3
- package/template/src/index.ts +3 -13
- package/template/src/tools/CreatePostTool.ts +15 -23
- package/template/src/tools/GetWeatherTool.ts +22 -23
- package/template/src/tools/UserDataTool.ts +56 -0
- package/template/src/services/MathService.ts +0 -61
- package/template/src/tools/AdvancedMathTool.ts +0 -82
- package/template/src/tools/CalculatorTool.ts +0 -65
- package/template/src/tools/GetUserDataTool.ts +0 -38
- package/template/tools/UserPreferencesTool.ts +0 -73
package/dist/services/api.js
CHANGED
|
@@ -200,24 +200,28 @@ export class ToolApi {
|
|
|
200
200
|
// User Data API calls
|
|
201
201
|
export class UserDataApi {
|
|
202
202
|
static async getUserData(apiKey, agentId) {
|
|
203
|
-
|
|
203
|
+
const response = await httpClient.get(`${BASE_URLS.LOCAL}/developer/user/data/agent/${agentId}`, {
|
|
204
204
|
Authorization: `Bearer ${apiKey}`,
|
|
205
205
|
});
|
|
206
|
+
return response;
|
|
206
207
|
}
|
|
207
208
|
static async createUserData(apiKey, agentId, data) {
|
|
208
|
-
|
|
209
|
+
const response = await httpClient.put(`${BASE_URLS.LOCAL}/developer/user/data/agent/${agentId}`, data, {
|
|
209
210
|
Authorization: `Bearer ${apiKey}`,
|
|
210
211
|
});
|
|
212
|
+
return response.data.data;
|
|
211
213
|
}
|
|
212
214
|
static async updateUserData(apiKey, agentId, data) {
|
|
213
|
-
|
|
215
|
+
const response = await httpClient.put(`${BASE_URLS.LOCAL}/developer/user/data/agent/${agentId}`, data, {
|
|
214
216
|
Authorization: `Bearer ${apiKey}`,
|
|
215
217
|
});
|
|
218
|
+
return response.data.data;
|
|
216
219
|
}
|
|
217
220
|
static async deleteUserData(apiKey, agentId) {
|
|
218
|
-
|
|
221
|
+
const response = await httpClient.delete(`${BASE_URLS.LOCAL}/developer/user/data/agent/${agentId}`, {
|
|
219
222
|
Authorization: `Bearer ${apiKey}`,
|
|
220
223
|
});
|
|
224
|
+
return response;
|
|
221
225
|
}
|
|
222
226
|
}
|
|
223
227
|
/**
|
package/dist/skill.d.ts
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import { ZodType } from "zod";
|
|
2
2
|
import { LuaTool } from "./types/index.js";
|
|
3
3
|
export { LuaTool };
|
|
4
|
+
/**
|
|
5
|
+
* Safe environment variable access function
|
|
6
|
+
* Gets injected at runtime with skill-specific environment variables
|
|
7
|
+
*
|
|
8
|
+
* @param key - The environment variable key to retrieve
|
|
9
|
+
* @returns The environment variable value or undefined if not found
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const baseUrl = env('BASE_URL');
|
|
14
|
+
* const apiKey = env('API_KEY');
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare const env: (key: string) => string | undefined;
|
|
4
18
|
export interface LuaSkillConfig {
|
|
5
19
|
description: string;
|
|
6
20
|
context: string;
|
|
@@ -25,6 +39,7 @@ export declare class LuaSkill {
|
|
|
25
39
|
* ```
|
|
26
40
|
*/
|
|
27
41
|
constructor(config: LuaSkillConfig);
|
|
28
|
-
addTool<TInput extends ZodType
|
|
42
|
+
addTool<TInput extends ZodType>(tool: LuaTool<TInput>): void;
|
|
43
|
+
addTools(tools: LuaTool<any>[]): void;
|
|
29
44
|
run(input: Record<string, any>): Promise<any>;
|
|
30
45
|
}
|
package/dist/skill.js
CHANGED
|
@@ -1,4 +1,46 @@
|
|
|
1
1
|
import { assertValidToolName } from "./types/index.js";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import yaml from "js-yaml";
|
|
5
|
+
/**
|
|
6
|
+
* Safe environment variable access function
|
|
7
|
+
* Gets injected at runtime with skill-specific environment variables
|
|
8
|
+
*
|
|
9
|
+
* @param key - The environment variable key to retrieve
|
|
10
|
+
* @returns The environment variable value or undefined if not found
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const baseUrl = env('BASE_URL');
|
|
15
|
+
* const apiKey = env('API_KEY');
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export const env = (key) => {
|
|
19
|
+
// Try to load environment variables from lua.skill.yaml
|
|
20
|
+
try {
|
|
21
|
+
// Look for lua.skill.yaml in current directory and parent directories
|
|
22
|
+
let currentDir = process.cwd();
|
|
23
|
+
let yamlPath = null;
|
|
24
|
+
while (currentDir !== path.dirname(currentDir)) {
|
|
25
|
+
const potentialPath = path.join(currentDir, 'lua.skill.yaml');
|
|
26
|
+
if (fs.existsSync(potentialPath)) {
|
|
27
|
+
yamlPath = potentialPath;
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
currentDir = path.dirname(currentDir);
|
|
31
|
+
}
|
|
32
|
+
if (yamlPath) {
|
|
33
|
+
const yamlContent = fs.readFileSync(yamlPath, 'utf8');
|
|
34
|
+
const config = yaml.load(yamlContent);
|
|
35
|
+
return config?.skill?.env?.[key];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
// If we can't load the YAML, fall back to undefined
|
|
40
|
+
console.warn(`Warning: Could not load environment variables from lua.skill.yaml: ${error}`);
|
|
41
|
+
}
|
|
42
|
+
return undefined;
|
|
43
|
+
};
|
|
2
44
|
export class LuaSkill {
|
|
3
45
|
/**
|
|
4
46
|
* Creates a new LuaSkill instance
|
|
@@ -25,6 +67,13 @@ export class LuaSkill {
|
|
|
25
67
|
assertValidToolName(tool.name);
|
|
26
68
|
this.tools.push(tool);
|
|
27
69
|
}
|
|
70
|
+
addTools(tools) {
|
|
71
|
+
// Validate all tool names before adding them
|
|
72
|
+
for (const tool of tools) {
|
|
73
|
+
assertValidToolName(tool.name);
|
|
74
|
+
}
|
|
75
|
+
this.tools.push(...tools);
|
|
76
|
+
}
|
|
28
77
|
async run(input) {
|
|
29
78
|
const tool = this.tools.find(tool => tool.name === input.tool);
|
|
30
79
|
if (!tool) {
|
package/dist/types/index.d.ts
CHANGED
|
@@ -62,11 +62,10 @@ export declare function validateToolName(name: string): boolean;
|
|
|
62
62
|
* Throws an error if the tool name is invalid
|
|
63
63
|
*/
|
|
64
64
|
export declare function assertValidToolName(name: string): void;
|
|
65
|
-
export interface LuaTool<TInput extends ZodType = ZodType
|
|
65
|
+
export interface LuaTool<TInput extends ZodType = ZodType> {
|
|
66
66
|
name: string;
|
|
67
67
|
description: string;
|
|
68
68
|
inputSchema: TInput;
|
|
69
|
-
outputSchema: TOutput;
|
|
70
69
|
execute: (input: any) => Promise<any>;
|
|
71
70
|
}
|
|
72
71
|
export interface LuaSkillConfig {
|
|
@@ -78,6 +77,7 @@ export declare class LuaSkill {
|
|
|
78
77
|
private readonly description;
|
|
79
78
|
private readonly context;
|
|
80
79
|
constructor(config: LuaSkillConfig);
|
|
81
|
-
addTool<TInput extends ZodType
|
|
80
|
+
addTool<TInput extends ZodType>(tool: LuaTool<TInput>): void;
|
|
81
|
+
addTools(tools: LuaTool<any>[]): void;
|
|
82
82
|
run(input: Record<string, any>): Promise<any>;
|
|
83
83
|
}
|
package/dist/user-data-api.d.ts
CHANGED
package/dist/user-data-api.js
CHANGED
|
@@ -3,13 +3,15 @@
|
|
|
3
3
|
* Provides methods to interact with user data stored in the Lua system
|
|
4
4
|
*/
|
|
5
5
|
export class UserDataAPI {
|
|
6
|
-
constructor() {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.userData = {};
|
|
8
|
+
}
|
|
7
9
|
/**
|
|
8
10
|
* Get user data for the current agent
|
|
9
11
|
* @returns Promise<UserDataResponse>
|
|
10
12
|
*/
|
|
11
13
|
async get() {
|
|
12
|
-
return { success: true };
|
|
14
|
+
return { success: true, data: this.userData };
|
|
13
15
|
}
|
|
14
16
|
/**
|
|
15
17
|
* Create or update user data for the current agent
|
|
@@ -17,7 +19,8 @@ export class UserDataAPI {
|
|
|
17
19
|
* @returns Promise<UserDataResponse>
|
|
18
20
|
*/
|
|
19
21
|
async create(data) {
|
|
20
|
-
|
|
22
|
+
this.userData = data;
|
|
23
|
+
return { success: true, data: this.userData };
|
|
21
24
|
}
|
|
22
25
|
/**
|
|
23
26
|
* Update existing user data for the current agent
|
|
@@ -26,13 +29,15 @@ export class UserDataAPI {
|
|
|
26
29
|
*/
|
|
27
30
|
async update(data) {
|
|
28
31
|
// Update is the same as create for this API
|
|
29
|
-
|
|
32
|
+
this.userData = { ...this.userData, ...data };
|
|
33
|
+
return { success: true, data: this.userData };
|
|
30
34
|
}
|
|
31
35
|
/**
|
|
32
36
|
* Clear all user data for the current agent
|
|
33
37
|
* @returns Promise<{success: boolean}>
|
|
34
38
|
*/
|
|
35
39
|
async clear() {
|
|
40
|
+
this.userData = {};
|
|
36
41
|
return { success: true };
|
|
37
42
|
}
|
|
38
43
|
}
|
package/dist/utils/files.js
CHANGED
|
@@ -27,10 +27,30 @@ export function copyTemplateFiles(templateDir, targetDir) {
|
|
|
27
27
|
function updatePackageJson(srcPath, destPath) {
|
|
28
28
|
// Read the template package.json
|
|
29
29
|
const templatePackageJson = JSON.parse(fs.readFileSync(srcPath, 'utf8'));
|
|
30
|
-
// Get the current CLI version from the
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
// Get the current CLI version from the CLI's own package.json
|
|
31
|
+
// We need to find the CLI's package.json, not the current working directory's
|
|
32
|
+
let currentCliVersion = '1.3.2-alpha.0'; // Default fallback version
|
|
33
|
+
try {
|
|
34
|
+
// Try to find the CLI's package.json by looking for it in common locations
|
|
35
|
+
const possiblePaths = [
|
|
36
|
+
path.join(__dirname, '..', '..', 'package.json'), // From dist/utils/
|
|
37
|
+
path.join(process.cwd(), 'package.json'), // Current directory (fallback)
|
|
38
|
+
path.join(process.env.HOME || '', '.npm-global', 'lib', 'node_modules', 'lua-cli', 'package.json'), // Global install
|
|
39
|
+
];
|
|
40
|
+
for (const packagePath of possiblePaths) {
|
|
41
|
+
if (fs.existsSync(packagePath)) {
|
|
42
|
+
const mainPackageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
|
43
|
+
if (mainPackageJson.name === 'lua-cli') {
|
|
44
|
+
currentCliVersion = mainPackageJson.version;
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
// If we can't read any package.json, use the fallback version
|
|
52
|
+
console.log(`Using fallback CLI version: ${currentCliVersion}`);
|
|
53
|
+
}
|
|
34
54
|
// Update the lua-cli dependency version
|
|
35
55
|
if (templatePackageJson.dependencies && templatePackageJson.dependencies['lua-cli']) {
|
|
36
56
|
templatePackageJson.dependencies['lua-cli'] = `^${currentCliVersion}`;
|
|
@@ -50,7 +70,15 @@ ${personaSection}${welcomeMessageSection}
|
|
|
50
70
|
skill:
|
|
51
71
|
name: "${skillName}"
|
|
52
72
|
version: "0.0.1"
|
|
53
|
-
${skillIdSection}
|
|
73
|
+
${skillIdSection} env:
|
|
74
|
+
# Example environment variables - customize these for your skill
|
|
75
|
+
API_URL: "https://api.example.com"
|
|
76
|
+
API_KEY: "your-api-key-here"
|
|
77
|
+
DEBUG_MODE: "false"
|
|
78
|
+
MAX_RETRIES: "3"
|
|
79
|
+
TIMEOUT_MS: "5000"
|
|
80
|
+
# Add your own environment variables below
|
|
81
|
+
# CUSTOM_VAR: "custom-value"`;
|
|
54
82
|
fs.writeFileSync("lua.skill.yaml", yamlContent);
|
|
55
83
|
}
|
|
56
84
|
export function readSkillYaml() {
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
export interface SandboxOptions {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
agentId: string;
|
|
4
|
+
customConsole?: any;
|
|
5
|
+
broadcastLog?: (logData: any) => void;
|
|
6
|
+
}
|
|
7
|
+
export interface ExecuteToolOptions extends SandboxOptions {
|
|
8
|
+
toolCode: string;
|
|
9
|
+
inputs: any;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Creates a VM sandbox context with all necessary globals and utilities
|
|
13
|
+
*/
|
|
14
|
+
export declare function createSandbox(options: SandboxOptions): {
|
|
15
|
+
require: NodeJS.Require;
|
|
16
|
+
console: any;
|
|
17
|
+
Buffer: BufferConstructor;
|
|
18
|
+
setTimeout: typeof setTimeout;
|
|
19
|
+
setInterval: typeof setInterval;
|
|
20
|
+
clearTimeout: typeof clearTimeout;
|
|
21
|
+
clearInterval: typeof clearInterval;
|
|
22
|
+
process: NodeJS.Process;
|
|
23
|
+
global: typeof globalThis;
|
|
24
|
+
__dirname: string;
|
|
25
|
+
__filename: string;
|
|
26
|
+
module: {
|
|
27
|
+
exports: {};
|
|
28
|
+
};
|
|
29
|
+
exports: {};
|
|
30
|
+
fetch: typeof fetch;
|
|
31
|
+
URLSearchParams: {
|
|
32
|
+
new (init?: string[][] | Record<string, string> | string | URLSearchParams): URLSearchParams;
|
|
33
|
+
prototype: URLSearchParams;
|
|
34
|
+
};
|
|
35
|
+
URL: {
|
|
36
|
+
new (url: string | URL, base?: string | URL): URL;
|
|
37
|
+
prototype: URL;
|
|
38
|
+
canParse(url: string | URL, base?: string | URL): boolean;
|
|
39
|
+
createObjectURL(obj: Blob | MediaSource): string;
|
|
40
|
+
parse(url: string | URL, base?: string | URL): URL | null;
|
|
41
|
+
revokeObjectURL(url: string): void;
|
|
42
|
+
};
|
|
43
|
+
Headers: {
|
|
44
|
+
new (init?: HeadersInit): Headers;
|
|
45
|
+
prototype: Headers;
|
|
46
|
+
};
|
|
47
|
+
Request: {
|
|
48
|
+
new (input: RequestInfo | URL, init?: RequestInit): Request;
|
|
49
|
+
prototype: Request;
|
|
50
|
+
};
|
|
51
|
+
Response: {
|
|
52
|
+
new (body?: BodyInit | null, init?: ResponseInit): Response;
|
|
53
|
+
prototype: Response;
|
|
54
|
+
error(): Response;
|
|
55
|
+
json(data: any, init?: ResponseInit): Response;
|
|
56
|
+
redirect(url: string | URL, status?: number): Response;
|
|
57
|
+
};
|
|
58
|
+
Object: ObjectConstructor;
|
|
59
|
+
Array: ArrayConstructor;
|
|
60
|
+
String: StringConstructor;
|
|
61
|
+
Number: NumberConstructor;
|
|
62
|
+
Boolean: BooleanConstructor;
|
|
63
|
+
Date: DateConstructor;
|
|
64
|
+
Math: Math;
|
|
65
|
+
JSON: JSON;
|
|
66
|
+
Error: ErrorConstructor;
|
|
67
|
+
TypeError: TypeErrorConstructor;
|
|
68
|
+
ReferenceError: ReferenceErrorConstructor;
|
|
69
|
+
SyntaxError: SyntaxErrorConstructor;
|
|
70
|
+
globalThis: typeof globalThis;
|
|
71
|
+
undefined: undefined;
|
|
72
|
+
null: null;
|
|
73
|
+
Infinity: number;
|
|
74
|
+
NaN: number;
|
|
75
|
+
user: {
|
|
76
|
+
data: {
|
|
77
|
+
update: (data: any) => Promise<import("../services/api.js").ApiResponse<any>>;
|
|
78
|
+
get: () => Promise<any>;
|
|
79
|
+
create: (data: any) => Promise<any>;
|
|
80
|
+
};
|
|
81
|
+
};
|
|
82
|
+
env: (key: string) => string;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Executes a tool in a VM sandbox
|
|
86
|
+
*/
|
|
87
|
+
export declare function executeTool(options: ExecuteToolOptions): Promise<any>;
|
|
88
|
+
/**
|
|
89
|
+
* Creates a custom console that broadcasts logs via WebSocket
|
|
90
|
+
*/
|
|
91
|
+
export declare function createBroadcastConsole(broadcastLog: (logData: any) => void): {
|
|
92
|
+
log: (...args: any[]) => void;
|
|
93
|
+
error: (...args: any[]) => void;
|
|
94
|
+
warn: (...args: any[]) => void;
|
|
95
|
+
info: (...args: any[]) => void;
|
|
96
|
+
};
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { createRequire } from "module";
|
|
2
|
+
import vm from "vm";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { UserDataApi } from "../services/api.js";
|
|
5
|
+
import { readSkillConfig } from "./files.js";
|
|
6
|
+
/**
|
|
7
|
+
* Creates a VM sandbox context with all necessary globals and utilities
|
|
8
|
+
*/
|
|
9
|
+
export function createSandbox(options) {
|
|
10
|
+
const { apiKey, agentId, customConsole, broadcastLog } = options;
|
|
11
|
+
// Extract environment variables from YAML config
|
|
12
|
+
const config = readSkillConfig();
|
|
13
|
+
const envVars = {};
|
|
14
|
+
if (config?.skill?.env) {
|
|
15
|
+
for (const [key, value] of Object.entries(config.skill.env)) {
|
|
16
|
+
envVars[key] = value;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
// Create a CommonJS context for execution
|
|
20
|
+
const require = createRequire(process.cwd() + '/package.json');
|
|
21
|
+
const updateUserData = async (data) => {
|
|
22
|
+
return await UserDataApi.updateUserData(apiKey, agentId, data);
|
|
23
|
+
};
|
|
24
|
+
const getUserData = async () => {
|
|
25
|
+
return await UserDataApi.getUserData(apiKey, agentId);
|
|
26
|
+
};
|
|
27
|
+
const linkUserData = async (data) => {
|
|
28
|
+
return await UserDataApi.createUserData(apiKey, agentId, data);
|
|
29
|
+
};
|
|
30
|
+
// Create console object (use custom console if provided, otherwise default)
|
|
31
|
+
const consoleObj = customConsole || console;
|
|
32
|
+
// Create a sandbox context
|
|
33
|
+
const sandbox = {
|
|
34
|
+
require,
|
|
35
|
+
console: consoleObj,
|
|
36
|
+
Buffer,
|
|
37
|
+
setTimeout,
|
|
38
|
+
setInterval,
|
|
39
|
+
clearTimeout,
|
|
40
|
+
clearInterval,
|
|
41
|
+
process,
|
|
42
|
+
global: globalThis,
|
|
43
|
+
__dirname: process.cwd(),
|
|
44
|
+
__filename: path.join(process.cwd(), 'index.ts'),
|
|
45
|
+
module: { exports: {} },
|
|
46
|
+
exports: {},
|
|
47
|
+
// Web APIs
|
|
48
|
+
fetch: globalThis.fetch,
|
|
49
|
+
URLSearchParams: globalThis.URLSearchParams,
|
|
50
|
+
URL: globalThis.URL,
|
|
51
|
+
Headers: globalThis.Headers,
|
|
52
|
+
Request: globalThis.Request,
|
|
53
|
+
Response: globalThis.Response,
|
|
54
|
+
// Additional globals
|
|
55
|
+
Object,
|
|
56
|
+
Array,
|
|
57
|
+
String,
|
|
58
|
+
Number,
|
|
59
|
+
Boolean,
|
|
60
|
+
Date,
|
|
61
|
+
Math,
|
|
62
|
+
JSON,
|
|
63
|
+
Error,
|
|
64
|
+
TypeError,
|
|
65
|
+
ReferenceError,
|
|
66
|
+
SyntaxError,
|
|
67
|
+
globalThis,
|
|
68
|
+
undefined: undefined,
|
|
69
|
+
null: null,
|
|
70
|
+
Infinity: Infinity,
|
|
71
|
+
NaN: NaN,
|
|
72
|
+
user: {
|
|
73
|
+
data: {
|
|
74
|
+
update: updateUserData,
|
|
75
|
+
get: getUserData,
|
|
76
|
+
create: linkUserData
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
// Environment variables function
|
|
80
|
+
env: (key) => envVars[key]
|
|
81
|
+
};
|
|
82
|
+
return sandbox;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Executes a tool in a VM sandbox
|
|
86
|
+
*/
|
|
87
|
+
export async function executeTool(options) {
|
|
88
|
+
const { toolCode, inputs } = options;
|
|
89
|
+
// Create sandbox
|
|
90
|
+
const sandbox = createSandbox(options);
|
|
91
|
+
// Create the CommonJS wrapper code
|
|
92
|
+
const commonJsWrapper = `
|
|
93
|
+
const executeFunction = ${toolCode};
|
|
94
|
+
|
|
95
|
+
// Export the function for testing
|
|
96
|
+
module.exports = async (input) => {
|
|
97
|
+
return await executeFunction(input);
|
|
98
|
+
};
|
|
99
|
+
`;
|
|
100
|
+
// Execute the code in the sandbox
|
|
101
|
+
const context = vm.createContext(sandbox);
|
|
102
|
+
vm.runInContext(commonJsWrapper, context);
|
|
103
|
+
// Get the exported function and execute it
|
|
104
|
+
const executeFunction = context.module.exports;
|
|
105
|
+
return await executeFunction(inputs);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Creates a custom console that broadcasts logs via WebSocket
|
|
109
|
+
*/
|
|
110
|
+
export function createBroadcastConsole(broadcastLog) {
|
|
111
|
+
return {
|
|
112
|
+
log: (...args) => {
|
|
113
|
+
const message = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' ');
|
|
114
|
+
broadcastLog({
|
|
115
|
+
type: 'log',
|
|
116
|
+
subType: 'info',
|
|
117
|
+
message: message,
|
|
118
|
+
timestamp: new Date().toISOString(),
|
|
119
|
+
id: Date.now().toString()
|
|
120
|
+
});
|
|
121
|
+
// Also log to server console
|
|
122
|
+
console.log(...args);
|
|
123
|
+
},
|
|
124
|
+
error: (...args) => {
|
|
125
|
+
const message = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' ');
|
|
126
|
+
broadcastLog({
|
|
127
|
+
type: 'log',
|
|
128
|
+
subType: 'error',
|
|
129
|
+
message: message,
|
|
130
|
+
timestamp: new Date().toISOString(),
|
|
131
|
+
id: Date.now().toString()
|
|
132
|
+
});
|
|
133
|
+
// Also log to server console
|
|
134
|
+
console.error(...args);
|
|
135
|
+
},
|
|
136
|
+
warn: (...args) => {
|
|
137
|
+
const message = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' ');
|
|
138
|
+
broadcastLog({
|
|
139
|
+
type: 'log',
|
|
140
|
+
subType: 'warn',
|
|
141
|
+
message: message,
|
|
142
|
+
timestamp: new Date().toISOString(),
|
|
143
|
+
id: Date.now().toString()
|
|
144
|
+
});
|
|
145
|
+
// Also log to server console
|
|
146
|
+
console.warn(...args);
|
|
147
|
+
},
|
|
148
|
+
info: (...args) => {
|
|
149
|
+
const message = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' ');
|
|
150
|
+
broadcastLog({
|
|
151
|
+
type: 'log',
|
|
152
|
+
subType: 'info',
|
|
153
|
+
message: message,
|
|
154
|
+
timestamp: new Date().toISOString(),
|
|
155
|
+
id: Date.now().toString()
|
|
156
|
+
});
|
|
157
|
+
// Also log to server console
|
|
158
|
+
console.info(...args);
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
}
|