@agentforge-ai/cli 0.6.0 → 0.7.0
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.
|
@@ -38,7 +38,7 @@ export const webSearch = createTool({
|
|
|
38
38
|
{
|
|
39
39
|
name: 'code-executor',
|
|
40
40
|
displayName: 'Code Executor',
|
|
41
|
-
description: '
|
|
41
|
+
description: 'Execute JavaScript/TypeScript code snippets via the AgentForge sandbox API and return the output.',
|
|
42
42
|
category: 'Tools',
|
|
43
43
|
version: '1.0.0',
|
|
44
44
|
author: 'AgentForge',
|
|
@@ -48,18 +48,25 @@ import { z } from 'zod';
|
|
|
48
48
|
|
|
49
49
|
export const codeExecutor = createTool({
|
|
50
50
|
id: 'code-executor',
|
|
51
|
-
description: 'Execute JavaScript code and return the result',
|
|
51
|
+
description: 'Execute JavaScript code via the sandbox API and return the result',
|
|
52
52
|
inputSchema: z.object({
|
|
53
53
|
code: z.string().describe('JavaScript code to execute'),
|
|
54
|
+
language: z.enum(['javascript', 'typescript']).default('javascript'),
|
|
54
55
|
}),
|
|
55
56
|
execute: async ({ context }) => {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
// Code is executed server-side via the AgentForge sandbox API,
|
|
58
|
+
// not via eval or Function constructor, to prevent arbitrary code execution risks.
|
|
59
|
+
const response = await fetch('/api/sandbox/execute', {
|
|
60
|
+
method: 'POST',
|
|
61
|
+
headers: { 'Content-Type': 'application/json' },
|
|
62
|
+
body: JSON.stringify({ code: context.code, language: context.language }),
|
|
63
|
+
});
|
|
64
|
+
if (!response.ok) {
|
|
65
|
+
const err = await response.json().catch(() => ({ error: 'Unknown error' }));
|
|
66
|
+
return { success: false, error: err.error ?? 'Sandbox execution failed' };
|
|
62
67
|
}
|
|
68
|
+
const data = await response.json();
|
|
69
|
+
return { success: true, output: String(data.output ?? '') };
|
|
63
70
|
},
|
|
64
71
|
});`,
|
|
65
72
|
},
|
|
@@ -74,16 +81,71 @@ export const codeExecutor = createTool({
|
|
|
74
81
|
code: `import { createTool } from '@mastra/core';
|
|
75
82
|
import { z } from 'zod';
|
|
76
83
|
|
|
84
|
+
// Safe arithmetic evaluator — no eval or Function constructor used.
|
|
85
|
+
function evaluateExpression(expr: string): number {
|
|
86
|
+
// Allow only digits, operators, parentheses, dots, and whitespace.
|
|
87
|
+
if (!/^[0-9+\\-*/().%\\s]+$/.test(expr)) {
|
|
88
|
+
throw new Error('Expression contains invalid characters');
|
|
89
|
+
}
|
|
90
|
+
// Recursive descent parser for: expr = term (('+' | '-') term)*
|
|
91
|
+
let pos = 0;
|
|
92
|
+
const peek = () => expr[pos] ?? '';
|
|
93
|
+
const consume = () => expr[pos++];
|
|
94
|
+
const skipWs = () => { while (peek() === ' ') consume(); };
|
|
95
|
+
|
|
96
|
+
function parseNumber(): number {
|
|
97
|
+
skipWs();
|
|
98
|
+
let num = '';
|
|
99
|
+
if (peek() === '(') { consume(); const v = parseExpr(); skipWs(); consume(); return v; }
|
|
100
|
+
while (/[0-9.]/.test(peek())) num += consume();
|
|
101
|
+
if (num === '') throw new Error('Expected number');
|
|
102
|
+
return parseFloat(num);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function parseFactor(): number {
|
|
106
|
+
skipWs();
|
|
107
|
+
if (peek() === '-') { consume(); return -parseFactor(); }
|
|
108
|
+
return parseNumber();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function parseTerm(): number {
|
|
112
|
+
let left = parseFactor();
|
|
113
|
+
skipWs();
|
|
114
|
+
while (peek() === '*' || peek() === '/') {
|
|
115
|
+
const op = consume(); skipWs();
|
|
116
|
+
const right = parseFactor();
|
|
117
|
+
left = op === '*' ? left * right : left / right;
|
|
118
|
+
skipWs();
|
|
119
|
+
}
|
|
120
|
+
return left;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function parseExpr(): number {
|
|
124
|
+
let left = parseTerm();
|
|
125
|
+
skipWs();
|
|
126
|
+
while (peek() === '+' || peek() === '-') {
|
|
127
|
+
const op = consume(); skipWs();
|
|
128
|
+
const right = parseTerm();
|
|
129
|
+
left = op === '+' ? left + right : left - right;
|
|
130
|
+
skipWs();
|
|
131
|
+
}
|
|
132
|
+
return left;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const result = parseExpr();
|
|
136
|
+
if (pos !== expr.length) throw new Error('Unexpected token at position ' + pos);
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
|
|
77
140
|
export const calculator = createTool({
|
|
78
141
|
id: 'calculator',
|
|
79
|
-
description: 'Evaluate a mathematical expression',
|
|
142
|
+
description: 'Evaluate a mathematical expression safely',
|
|
80
143
|
inputSchema: z.object({
|
|
81
144
|
expression: z.string().describe('Math expression to evaluate, e.g. "2 + 2 * 3"'),
|
|
82
145
|
}),
|
|
83
146
|
execute: async ({ context }) => {
|
|
84
147
|
try {
|
|
85
|
-
const
|
|
86
|
-
const result = Function('"use strict"; return (' + sanitized + ')')();
|
|
148
|
+
const result = evaluateExpression(context.expression.trim());
|
|
87
149
|
return { result: Number(result), expression: context.expression };
|
|
88
150
|
} catch (error: any) {
|
|
89
151
|
return { error: 'Invalid expression: ' + error.message };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentforge-ai/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "CLI tool for creating, running, and managing AgentForge projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"fs-extra": "^11.2.0",
|
|
20
20
|
"gray-matter": "^4.0.3",
|
|
21
21
|
"ora": "^8.0.0",
|
|
22
|
-
"prompts": "^2.4.2"
|
|
22
|
+
"prompts": "^2.4.2",
|
|
23
|
+
"@agentforge-ai/core": "0.7.0"
|
|
23
24
|
},
|
|
24
25
|
"devDependencies": {
|
|
25
26
|
"@types/fs-extra": "^11.0.4",
|
|
@@ -38,7 +38,7 @@ export const webSearch = createTool({
|
|
|
38
38
|
{
|
|
39
39
|
name: 'code-executor',
|
|
40
40
|
displayName: 'Code Executor',
|
|
41
|
-
description: '
|
|
41
|
+
description: 'Execute JavaScript/TypeScript code snippets via the AgentForge sandbox API and return the output.',
|
|
42
42
|
category: 'Tools',
|
|
43
43
|
version: '1.0.0',
|
|
44
44
|
author: 'AgentForge',
|
|
@@ -48,18 +48,25 @@ import { z } from 'zod';
|
|
|
48
48
|
|
|
49
49
|
export const codeExecutor = createTool({
|
|
50
50
|
id: 'code-executor',
|
|
51
|
-
description: 'Execute JavaScript code and return the result',
|
|
51
|
+
description: 'Execute JavaScript code via the sandbox API and return the result',
|
|
52
52
|
inputSchema: z.object({
|
|
53
53
|
code: z.string().describe('JavaScript code to execute'),
|
|
54
|
+
language: z.enum(['javascript', 'typescript']).default('javascript'),
|
|
54
55
|
}),
|
|
55
56
|
execute: async ({ context }) => {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
// Code is executed server-side via the AgentForge sandbox API,
|
|
58
|
+
// not via eval or Function constructor, to prevent arbitrary code execution risks.
|
|
59
|
+
const response = await fetch('/api/sandbox/execute', {
|
|
60
|
+
method: 'POST',
|
|
61
|
+
headers: { 'Content-Type': 'application/json' },
|
|
62
|
+
body: JSON.stringify({ code: context.code, language: context.language }),
|
|
63
|
+
});
|
|
64
|
+
if (!response.ok) {
|
|
65
|
+
const err = await response.json().catch(() => ({ error: 'Unknown error' }));
|
|
66
|
+
return { success: false, error: err.error ?? 'Sandbox execution failed' };
|
|
62
67
|
}
|
|
68
|
+
const data = await response.json();
|
|
69
|
+
return { success: true, output: String(data.output ?? '') };
|
|
63
70
|
},
|
|
64
71
|
});`,
|
|
65
72
|
},
|
|
@@ -74,16 +81,71 @@ export const codeExecutor = createTool({
|
|
|
74
81
|
code: `import { createTool } from '@mastra/core';
|
|
75
82
|
import { z } from 'zod';
|
|
76
83
|
|
|
84
|
+
// Safe arithmetic evaluator — no eval or Function constructor used.
|
|
85
|
+
function evaluateExpression(expr: string): number {
|
|
86
|
+
// Allow only digits, operators, parentheses, dots, and whitespace.
|
|
87
|
+
if (!/^[0-9+\\-*/().%\\s]+$/.test(expr)) {
|
|
88
|
+
throw new Error('Expression contains invalid characters');
|
|
89
|
+
}
|
|
90
|
+
// Recursive descent parser for: expr = term (('+' | '-') term)*
|
|
91
|
+
let pos = 0;
|
|
92
|
+
const peek = () => expr[pos] ?? '';
|
|
93
|
+
const consume = () => expr[pos++];
|
|
94
|
+
const skipWs = () => { while (peek() === ' ') consume(); };
|
|
95
|
+
|
|
96
|
+
function parseNumber(): number {
|
|
97
|
+
skipWs();
|
|
98
|
+
let num = '';
|
|
99
|
+
if (peek() === '(') { consume(); const v = parseExpr(); skipWs(); consume(); return v; }
|
|
100
|
+
while (/[0-9.]/.test(peek())) num += consume();
|
|
101
|
+
if (num === '') throw new Error('Expected number');
|
|
102
|
+
return parseFloat(num);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function parseFactor(): number {
|
|
106
|
+
skipWs();
|
|
107
|
+
if (peek() === '-') { consume(); return -parseFactor(); }
|
|
108
|
+
return parseNumber();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function parseTerm(): number {
|
|
112
|
+
let left = parseFactor();
|
|
113
|
+
skipWs();
|
|
114
|
+
while (peek() === '*' || peek() === '/') {
|
|
115
|
+
const op = consume(); skipWs();
|
|
116
|
+
const right = parseFactor();
|
|
117
|
+
left = op === '*' ? left * right : left / right;
|
|
118
|
+
skipWs();
|
|
119
|
+
}
|
|
120
|
+
return left;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function parseExpr(): number {
|
|
124
|
+
let left = parseTerm();
|
|
125
|
+
skipWs();
|
|
126
|
+
while (peek() === '+' || peek() === '-') {
|
|
127
|
+
const op = consume(); skipWs();
|
|
128
|
+
const right = parseTerm();
|
|
129
|
+
left = op === '+' ? left + right : left - right;
|
|
130
|
+
skipWs();
|
|
131
|
+
}
|
|
132
|
+
return left;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const result = parseExpr();
|
|
136
|
+
if (pos !== expr.length) throw new Error('Unexpected token at position ' + pos);
|
|
137
|
+
return result;
|
|
138
|
+
}
|
|
139
|
+
|
|
77
140
|
export const calculator = createTool({
|
|
78
141
|
id: 'calculator',
|
|
79
|
-
description: 'Evaluate a mathematical expression',
|
|
142
|
+
description: 'Evaluate a mathematical expression safely',
|
|
80
143
|
inputSchema: z.object({
|
|
81
144
|
expression: z.string().describe('Math expression to evaluate, e.g. "2 + 2 * 3"'),
|
|
82
145
|
}),
|
|
83
146
|
execute: async ({ context }) => {
|
|
84
147
|
try {
|
|
85
|
-
const
|
|
86
|
-
const result = Function('"use strict"; return (' + sanitized + ')')();
|
|
148
|
+
const result = evaluateExpression(context.expression.trim());
|
|
87
149
|
return { result: Number(result), expression: context.expression };
|
|
88
150
|
} catch (error: any) {
|
|
89
151
|
return { error: 'Invalid expression: ' + error.message };
|