praisonai 1.7.0 → 1.7.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/agent/simple.js +19 -2
- package/dist/ai/agent-loop.d.ts +4 -0
- package/dist/ai/agent-loop.js +33 -10
- package/dist/cli/features/external-agents.d.ts +23 -0
- package/dist/cli/features/external-agents.js +84 -0
- package/dist/cli/features/sandbox-executor.d.ts +7 -1
- package/dist/cli/features/sandbox-executor.js +65 -15
- package/dist/index.d.ts +3 -2
- package/dist/index.js +79 -14
- package/dist/mcp/security.d.ts +4 -0
- package/dist/mcp/security.js +33 -10
- package/dist/mcp/server.d.ts +7 -0
- package/dist/mcp/server.js +25 -0
- package/dist/os/agentos.js +19 -0
- package/dist/os/config.d.ts +2 -0
- package/dist/os/config.js +3 -0
- package/dist/parity/index.d.ts +1104 -0
- package/dist/parity/index.js +1366 -0
- package/dist/tools/builtins/code-mode.js +16 -16
- package/dist/tools/index.d.ts +5 -2
- package/dist/tools/index.js +32 -5
- package/dist/tools/registry/index.d.ts +2 -2
- package/dist/tools/registry/index.js +10 -1
- package/dist/tools/registry/registry.d.ts +33 -0
- package/dist/tools/registry/registry.js +79 -1
- package/dist/tools/registry/types.d.ts +17 -0
- package/dist/tools/registry/types.js +22 -1
- package/dist/tools/utility-tools.js +39 -9
- package/dist/workflows/yaml-parser.d.ts +4 -1
- package/dist/workflows/yaml-parser.js +42 -5
- package/package.json +2 -2
|
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
9
9
|
exports.CODE_MODE_METADATA = void 0;
|
|
10
10
|
exports.codeMode = codeMode;
|
|
11
11
|
exports.createCodeModeTool = createCodeModeTool;
|
|
12
|
+
const node_vm_1 = require("node:vm");
|
|
12
13
|
exports.CODE_MODE_METADATA = {
|
|
13
14
|
id: 'code-mode',
|
|
14
15
|
displayName: 'Code Mode',
|
|
@@ -69,6 +70,10 @@ function codeMode(config) {
|
|
|
69
70
|
/import\s+.*from\s+['"]child_process['"]/,
|
|
70
71
|
/process\.exit/,
|
|
71
72
|
/eval\s*\(/,
|
|
73
|
+
/Function\s*\(/,
|
|
74
|
+
/\.constructor/,
|
|
75
|
+
/globalThis/,
|
|
76
|
+
/\bprocess\b/,
|
|
72
77
|
];
|
|
73
78
|
if (!settings.allowNetwork) {
|
|
74
79
|
blockedPatterns.push(/require\s*\(\s*['"]http['"]\s*\)/, /require\s*\(\s*['"]https['"]\s*\)/, /require\s*\(\s*['"]net['"]\s*\)/, /fetch\s*\(/);
|
|
@@ -101,37 +106,32 @@ function codeMode(config) {
|
|
|
101
106
|
}
|
|
102
107
|
}
|
|
103
108
|
try {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const sandbox = {
|
|
109
|
+
const stdout = [];
|
|
110
|
+
const stderr = [];
|
|
111
|
+
const sandboxContext = {
|
|
108
112
|
console: {
|
|
109
113
|
log: (...args) => stdout.push(args.map(String).join(' ')),
|
|
110
114
|
error: (...args) => stderr.push(args.map(String).join(' ')),
|
|
111
115
|
warn: (...args) => stderr.push(args.map(String).join(' ')),
|
|
112
116
|
},
|
|
113
|
-
setTimeout: undefined,
|
|
114
|
-
setInterval: undefined,
|
|
115
|
-
setImmediate: undefined,
|
|
116
|
-
process: undefined,
|
|
117
|
-
require: undefined,
|
|
118
117
|
__dirname: '/sandbox',
|
|
119
118
|
__filename: '/sandbox/index.js',
|
|
120
119
|
env: env || {},
|
|
121
120
|
files: files || {},
|
|
122
121
|
};
|
|
123
|
-
const stdout = [];
|
|
124
|
-
const stderr = [];
|
|
125
|
-
// Execute with timeout
|
|
126
122
|
const timeoutPromise = new Promise((_, reject) => {
|
|
127
123
|
setTimeout(() => reject(new Error('Execution timeout')), settings.timeoutMs);
|
|
128
124
|
});
|
|
129
125
|
const executePromise = new Promise((resolve, reject) => {
|
|
130
126
|
try {
|
|
131
|
-
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
127
|
+
const wrappedCode = `(async function() { ${code} })()`;
|
|
128
|
+
const result = (0, node_vm_1.runInNewContext)(wrappedCode, sandboxContext, {
|
|
129
|
+
timeout: settings.timeoutMs,
|
|
130
|
+
displayErrors: true,
|
|
131
|
+
});
|
|
132
|
+
Promise.resolve(result)
|
|
133
|
+
.then((value) => resolve(String(value ?? '')))
|
|
134
|
+
.catch(reject);
|
|
135
135
|
}
|
|
136
136
|
catch (error) {
|
|
137
137
|
reject(error);
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
export { BaseTool, ToolResult, ToolValidationError, validateTool, createTool, type ToolParameters } from './base';
|
|
2
|
-
export
|
|
2
|
+
export { tool, FunctionTool, ToolRegistry, getRegistry, registerTool, getTool, type ToolConfig, type ToolContext, } from './decorator';
|
|
3
3
|
export * from './arxivTools';
|
|
4
4
|
export * from './mcpSse';
|
|
5
|
-
export
|
|
5
|
+
export { ToolsRegistry, getToolsRegistry, createToolsRegistry, resetToolsRegistry, get_registry, get_tool, register_tool, validate_tool, } from './registry';
|
|
6
|
+
export type { ToolExecutionContext, ToolLimits, RedactionHooks, ToolLogger, ToolCapabilities, InstallHints, ToolMetadata, ToolExecutionResult, PraisonTool, ToolParameterSchema, ToolParameterProperty, ToolMiddleware, ToolHooks, ToolFactory, RegisteredTool, ToolInstallStatus, } from './registry';
|
|
7
|
+
export { MissingDependencyError, MissingEnvVarError, BudgetExceededError } from './registry';
|
|
8
|
+
export { createLoggingMiddleware, createTimeoutMiddleware, createRedactionMiddleware, createRateLimitMiddleware, createRetryMiddleware, createTracingMiddleware, createValidationMiddleware, composeMiddleware, } from './registry';
|
|
6
9
|
export * from './builtins';
|
|
7
10
|
export { tools, registerBuiltinTools } from './tools';
|
|
8
11
|
export type { default as ToolsFacade } from './tools';
|
package/dist/tools/index.js
CHANGED
|
@@ -14,20 +14,47 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.createDelegator = exports.createSubagentTools = exports.createSubagentTool = exports.SubagentTool = exports.registerBuiltinTools = exports.tools = exports.createTool = exports.validateTool = exports.ToolValidationError = exports.BaseTool = void 0;
|
|
17
|
+
exports.createDelegator = exports.createSubagentTools = exports.createSubagentTool = exports.SubagentTool = exports.registerBuiltinTools = exports.tools = exports.composeMiddleware = exports.createValidationMiddleware = exports.createTracingMiddleware = exports.createRetryMiddleware = exports.createRateLimitMiddleware = exports.createRedactionMiddleware = exports.createTimeoutMiddleware = exports.createLoggingMiddleware = exports.BudgetExceededError = exports.MissingEnvVarError = exports.MissingDependencyError = exports.validate_tool = exports.register_tool = exports.get_tool = exports.get_registry = exports.resetToolsRegistry = exports.createToolsRegistry = exports.getToolsRegistry = exports.ToolsRegistry = exports.getTool = exports.registerTool = exports.getRegistry = exports.ToolRegistry = exports.FunctionTool = exports.tool = exports.createTool = exports.validateTool = exports.ToolValidationError = exports.BaseTool = void 0;
|
|
18
18
|
// Export base tool interfaces and classes
|
|
19
19
|
var base_1 = require("./base");
|
|
20
20
|
Object.defineProperty(exports, "BaseTool", { enumerable: true, get: function () { return base_1.BaseTool; } });
|
|
21
21
|
Object.defineProperty(exports, "ToolValidationError", { enumerable: true, get: function () { return base_1.ToolValidationError; } });
|
|
22
22
|
Object.defineProperty(exports, "validateTool", { enumerable: true, get: function () { return base_1.validateTool; } });
|
|
23
23
|
Object.defineProperty(exports, "createTool", { enumerable: true, get: function () { return base_1.createTool; } });
|
|
24
|
-
//
|
|
25
|
-
|
|
24
|
+
// Legacy @tool decorator registry (camelCase names reserved for this API)
|
|
25
|
+
var decorator_1 = require("./decorator");
|
|
26
|
+
Object.defineProperty(exports, "tool", { enumerable: true, get: function () { return decorator_1.tool; } });
|
|
27
|
+
Object.defineProperty(exports, "FunctionTool", { enumerable: true, get: function () { return decorator_1.FunctionTool; } });
|
|
28
|
+
Object.defineProperty(exports, "ToolRegistry", { enumerable: true, get: function () { return decorator_1.ToolRegistry; } });
|
|
29
|
+
Object.defineProperty(exports, "getRegistry", { enumerable: true, get: function () { return decorator_1.getRegistry; } });
|
|
30
|
+
Object.defineProperty(exports, "registerTool", { enumerable: true, get: function () { return decorator_1.registerTool; } });
|
|
31
|
+
Object.defineProperty(exports, "getTool", { enumerable: true, get: function () { return decorator_1.getTool; } });
|
|
26
32
|
// Export all tool modules
|
|
27
33
|
__exportStar(require("./arxivTools"), exports);
|
|
28
34
|
__exportStar(require("./mcpSse"), exports);
|
|
29
|
-
//
|
|
30
|
-
|
|
35
|
+
// New AI SDK tools registry — snake_case parity names (avoid camelCase clash with decorator)
|
|
36
|
+
var registry_1 = require("./registry");
|
|
37
|
+
Object.defineProperty(exports, "ToolsRegistry", { enumerable: true, get: function () { return registry_1.ToolsRegistry; } });
|
|
38
|
+
Object.defineProperty(exports, "getToolsRegistry", { enumerable: true, get: function () { return registry_1.getToolsRegistry; } });
|
|
39
|
+
Object.defineProperty(exports, "createToolsRegistry", { enumerable: true, get: function () { return registry_1.createToolsRegistry; } });
|
|
40
|
+
Object.defineProperty(exports, "resetToolsRegistry", { enumerable: true, get: function () { return registry_1.resetToolsRegistry; } });
|
|
41
|
+
Object.defineProperty(exports, "get_registry", { enumerable: true, get: function () { return registry_1.get_registry; } });
|
|
42
|
+
Object.defineProperty(exports, "get_tool", { enumerable: true, get: function () { return registry_1.get_tool; } });
|
|
43
|
+
Object.defineProperty(exports, "register_tool", { enumerable: true, get: function () { return registry_1.register_tool; } });
|
|
44
|
+
Object.defineProperty(exports, "validate_tool", { enumerable: true, get: function () { return registry_1.validate_tool; } });
|
|
45
|
+
var registry_2 = require("./registry");
|
|
46
|
+
Object.defineProperty(exports, "MissingDependencyError", { enumerable: true, get: function () { return registry_2.MissingDependencyError; } });
|
|
47
|
+
Object.defineProperty(exports, "MissingEnvVarError", { enumerable: true, get: function () { return registry_2.MissingEnvVarError; } });
|
|
48
|
+
Object.defineProperty(exports, "BudgetExceededError", { enumerable: true, get: function () { return registry_2.BudgetExceededError; } });
|
|
49
|
+
var registry_3 = require("./registry");
|
|
50
|
+
Object.defineProperty(exports, "createLoggingMiddleware", { enumerable: true, get: function () { return registry_3.createLoggingMiddleware; } });
|
|
51
|
+
Object.defineProperty(exports, "createTimeoutMiddleware", { enumerable: true, get: function () { return registry_3.createTimeoutMiddleware; } });
|
|
52
|
+
Object.defineProperty(exports, "createRedactionMiddleware", { enumerable: true, get: function () { return registry_3.createRedactionMiddleware; } });
|
|
53
|
+
Object.defineProperty(exports, "createRateLimitMiddleware", { enumerable: true, get: function () { return registry_3.createRateLimitMiddleware; } });
|
|
54
|
+
Object.defineProperty(exports, "createRetryMiddleware", { enumerable: true, get: function () { return registry_3.createRetryMiddleware; } });
|
|
55
|
+
Object.defineProperty(exports, "createTracingMiddleware", { enumerable: true, get: function () { return registry_3.createTracingMiddleware; } });
|
|
56
|
+
Object.defineProperty(exports, "createValidationMiddleware", { enumerable: true, get: function () { return registry_3.createValidationMiddleware; } });
|
|
57
|
+
Object.defineProperty(exports, "composeMiddleware", { enumerable: true, get: function () { return registry_3.composeMiddleware; } });
|
|
31
58
|
// Export built-in tools
|
|
32
59
|
__exportStar(require("./builtins"), exports);
|
|
33
60
|
// Export tools facade
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
* Lazy-loaded exports for the tools registry system.
|
|
5
5
|
*/
|
|
6
6
|
export type { ToolExecutionContext, ToolLimits, RedactionHooks, ToolLogger, ToolCapabilities, InstallHints, ToolMetadata, ToolExecutionResult, PraisonTool, ToolParameterSchema, ToolParameterProperty, ToolMiddleware, ToolHooks, ToolFactory, RegisteredTool, ToolInstallStatus, } from './types';
|
|
7
|
-
export { MissingDependencyError, MissingEnvVarError } from './types';
|
|
8
|
-
export { ToolsRegistry, getToolsRegistry, createToolsRegistry, resetToolsRegistry, } from './registry';
|
|
7
|
+
export { MissingDependencyError, MissingEnvVarError, BudgetExceededError } from './types';
|
|
8
|
+
export { ToolsRegistry, getToolsRegistry, createToolsRegistry, resetToolsRegistry, get_registry, getRegistry, get_tool, getTool, register_tool, registerTool, validate_tool, validateTool, } from './registry';
|
|
9
9
|
export { createLoggingMiddleware, createTimeoutMiddleware, createRedactionMiddleware, createRateLimitMiddleware, createRetryMiddleware, createTracingMiddleware, createValidationMiddleware, composeMiddleware, } from './middleware';
|
|
@@ -5,17 +5,26 @@
|
|
|
5
5
|
* Lazy-loaded exports for the tools registry system.
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.composeMiddleware = exports.createValidationMiddleware = exports.createTracingMiddleware = exports.createRetryMiddleware = exports.createRateLimitMiddleware = exports.createRedactionMiddleware = exports.createTimeoutMiddleware = exports.createLoggingMiddleware = exports.resetToolsRegistry = exports.createToolsRegistry = exports.getToolsRegistry = exports.ToolsRegistry = exports.MissingEnvVarError = exports.MissingDependencyError = void 0;
|
|
8
|
+
exports.composeMiddleware = exports.createValidationMiddleware = exports.createTracingMiddleware = exports.createRetryMiddleware = exports.createRateLimitMiddleware = exports.createRedactionMiddleware = exports.createTimeoutMiddleware = exports.createLoggingMiddleware = exports.validateTool = exports.validate_tool = exports.registerTool = exports.register_tool = exports.getTool = exports.get_tool = exports.getRegistry = exports.get_registry = exports.resetToolsRegistry = exports.createToolsRegistry = exports.getToolsRegistry = exports.ToolsRegistry = exports.BudgetExceededError = exports.MissingEnvVarError = exports.MissingDependencyError = void 0;
|
|
9
9
|
// Errors
|
|
10
10
|
var types_1 = require("./types");
|
|
11
11
|
Object.defineProperty(exports, "MissingDependencyError", { enumerable: true, get: function () { return types_1.MissingDependencyError; } });
|
|
12
12
|
Object.defineProperty(exports, "MissingEnvVarError", { enumerable: true, get: function () { return types_1.MissingEnvVarError; } });
|
|
13
|
+
Object.defineProperty(exports, "BudgetExceededError", { enumerable: true, get: function () { return types_1.BudgetExceededError; } });
|
|
13
14
|
// Registry
|
|
14
15
|
var registry_1 = require("./registry");
|
|
15
16
|
Object.defineProperty(exports, "ToolsRegistry", { enumerable: true, get: function () { return registry_1.ToolsRegistry; } });
|
|
16
17
|
Object.defineProperty(exports, "getToolsRegistry", { enumerable: true, get: function () { return registry_1.getToolsRegistry; } });
|
|
17
18
|
Object.defineProperty(exports, "createToolsRegistry", { enumerable: true, get: function () { return registry_1.createToolsRegistry; } });
|
|
18
19
|
Object.defineProperty(exports, "resetToolsRegistry", { enumerable: true, get: function () { return registry_1.resetToolsRegistry; } });
|
|
20
|
+
Object.defineProperty(exports, "get_registry", { enumerable: true, get: function () { return registry_1.get_registry; } });
|
|
21
|
+
Object.defineProperty(exports, "getRegistry", { enumerable: true, get: function () { return registry_1.getRegistry; } });
|
|
22
|
+
Object.defineProperty(exports, "get_tool", { enumerable: true, get: function () { return registry_1.get_tool; } });
|
|
23
|
+
Object.defineProperty(exports, "getTool", { enumerable: true, get: function () { return registry_1.getTool; } });
|
|
24
|
+
Object.defineProperty(exports, "register_tool", { enumerable: true, get: function () { return registry_1.register_tool; } });
|
|
25
|
+
Object.defineProperty(exports, "registerTool", { enumerable: true, get: function () { return registry_1.registerTool; } });
|
|
26
|
+
Object.defineProperty(exports, "validate_tool", { enumerable: true, get: function () { return registry_1.validate_tool; } });
|
|
27
|
+
Object.defineProperty(exports, "validateTool", { enumerable: true, get: function () { return registry_1.validateTool; } });
|
|
19
28
|
// Middleware
|
|
20
29
|
var middleware_1 = require("./middleware");
|
|
21
30
|
Object.defineProperty(exports, "createLoggingMiddleware", { enumerable: true, get: function () { return middleware_1.createLoggingMiddleware; } });
|
|
@@ -90,3 +90,36 @@ export declare function createToolsRegistry(): ToolsRegistry;
|
|
|
90
90
|
* Reset the global registry (mainly for testing)
|
|
91
91
|
*/
|
|
92
92
|
export declare function resetToolsRegistry(): void;
|
|
93
|
+
/**
|
|
94
|
+
* Get the global registry instance (alias for getToolsRegistry)
|
|
95
|
+
* For Python SDK parity: get_registry()
|
|
96
|
+
*/
|
|
97
|
+
export declare function get_registry(): ToolsRegistry;
|
|
98
|
+
/** camelCase alias for get_registry — idiomatic TypeScript */
|
|
99
|
+
export declare const getRegistry: typeof get_registry;
|
|
100
|
+
/**
|
|
101
|
+
* Get a single tool by name from the global registry
|
|
102
|
+
* For Python SDK parity: get_tool()
|
|
103
|
+
*/
|
|
104
|
+
export declare function get_tool<TConfig = unknown, TInput = unknown, TOutput = unknown>(id: string, config?: TConfig): PraisonTool<TInput, TOutput> | null;
|
|
105
|
+
/** camelCase alias for get_tool — idiomatic TypeScript */
|
|
106
|
+
export declare const getTool: typeof get_tool;
|
|
107
|
+
/**
|
|
108
|
+
* Register a tool with the global registry
|
|
109
|
+
* For Python SDK parity: register_tool()
|
|
110
|
+
*/
|
|
111
|
+
export declare function register_tool(metadata: ToolMetadata, factory: ToolFactory): void;
|
|
112
|
+
/** camelCase alias for register_tool — idiomatic TypeScript */
|
|
113
|
+
export declare const registerTool: typeof register_tool;
|
|
114
|
+
/**
|
|
115
|
+
* Validate a tool's configuration and dependencies
|
|
116
|
+
* For Python SDK parity: validate_tool()
|
|
117
|
+
*/
|
|
118
|
+
export declare function validate_tool(id: string): Promise<{
|
|
119
|
+
valid: boolean;
|
|
120
|
+
installed: boolean;
|
|
121
|
+
missingEnvVars: string[];
|
|
122
|
+
errors: string[];
|
|
123
|
+
}>;
|
|
124
|
+
/** camelCase alias for validate_tool — idiomatic TypeScript */
|
|
125
|
+
export declare const validateTool: typeof validate_tool;
|
|
@@ -39,10 +39,14 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
39
39
|
};
|
|
40
40
|
})();
|
|
41
41
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
-
exports.ToolsRegistry = void 0;
|
|
42
|
+
exports.validateTool = exports.registerTool = exports.getTool = exports.getRegistry = exports.ToolsRegistry = void 0;
|
|
43
43
|
exports.getToolsRegistry = getToolsRegistry;
|
|
44
44
|
exports.createToolsRegistry = createToolsRegistry;
|
|
45
45
|
exports.resetToolsRegistry = resetToolsRegistry;
|
|
46
|
+
exports.get_registry = get_registry;
|
|
47
|
+
exports.get_tool = get_tool;
|
|
48
|
+
exports.register_tool = register_tool;
|
|
49
|
+
exports.validate_tool = validate_tool;
|
|
46
50
|
/**
|
|
47
51
|
* Tools Registry - Manages tool registration, lookup, and instantiation
|
|
48
52
|
*/
|
|
@@ -278,3 +282,77 @@ function resetToolsRegistry() {
|
|
|
278
282
|
}
|
|
279
283
|
globalRegistry = null;
|
|
280
284
|
}
|
|
285
|
+
/**
|
|
286
|
+
* Get the global registry instance (alias for getToolsRegistry)
|
|
287
|
+
* For Python SDK parity: get_registry()
|
|
288
|
+
*/
|
|
289
|
+
function get_registry() {
|
|
290
|
+
return getToolsRegistry();
|
|
291
|
+
}
|
|
292
|
+
/** camelCase alias for get_registry — idiomatic TypeScript */
|
|
293
|
+
exports.getRegistry = get_registry;
|
|
294
|
+
/**
|
|
295
|
+
* Get a single tool by name from the global registry
|
|
296
|
+
* For Python SDK parity: get_tool()
|
|
297
|
+
*/
|
|
298
|
+
function get_tool(id, config) {
|
|
299
|
+
try {
|
|
300
|
+
const registry = getToolsRegistry();
|
|
301
|
+
return registry.create(id, config);
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
return null;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
/** camelCase alias for get_tool — idiomatic TypeScript */
|
|
308
|
+
exports.getTool = get_tool;
|
|
309
|
+
/**
|
|
310
|
+
* Register a tool with the global registry
|
|
311
|
+
* For Python SDK parity: register_tool()
|
|
312
|
+
*/
|
|
313
|
+
function register_tool(metadata, factory) {
|
|
314
|
+
const registry = getToolsRegistry();
|
|
315
|
+
registry.register(metadata, factory);
|
|
316
|
+
}
|
|
317
|
+
/** camelCase alias for register_tool — idiomatic TypeScript */
|
|
318
|
+
exports.registerTool = register_tool;
|
|
319
|
+
/**
|
|
320
|
+
* Validate a tool's configuration and dependencies
|
|
321
|
+
* For Python SDK parity: validate_tool()
|
|
322
|
+
*/
|
|
323
|
+
async function validate_tool(id) {
|
|
324
|
+
const registry = getToolsRegistry();
|
|
325
|
+
if (!registry.has(id)) {
|
|
326
|
+
return {
|
|
327
|
+
valid: false,
|
|
328
|
+
installed: false,
|
|
329
|
+
missingEnvVars: [],
|
|
330
|
+
errors: [`Tool "${id}" is not registered`]
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
const status = await registry.getInstallStatus(id);
|
|
334
|
+
if (!status) {
|
|
335
|
+
return {
|
|
336
|
+
valid: false,
|
|
337
|
+
installed: false,
|
|
338
|
+
missingEnvVars: [],
|
|
339
|
+
errors: [`Failed to get status for tool "${id}"`]
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
const errors = [];
|
|
343
|
+
if (!status.installed) {
|
|
344
|
+
const installCmd = status.installCommand ?? `npm install ${registry.getMetadata(id)?.packageName ?? id}`;
|
|
345
|
+
errors.push(`Package dependency not installed. Run: ${installCmd}`);
|
|
346
|
+
}
|
|
347
|
+
if (status.missingEnvVars.length > 0) {
|
|
348
|
+
errors.push(`Missing environment variables: ${status.missingEnvVars.join(', ')}`);
|
|
349
|
+
}
|
|
350
|
+
return {
|
|
351
|
+
valid: status.installed && status.missingEnvVars.length === 0,
|
|
352
|
+
installed: status.installed,
|
|
353
|
+
missingEnvVars: status.missingEnvVars,
|
|
354
|
+
errors
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
/** camelCase alias for validate_tool — idiomatic TypeScript */
|
|
358
|
+
exports.validateTool = validate_tool;
|
|
@@ -215,3 +215,20 @@ export declare class MissingEnvVarError extends Error {
|
|
|
215
215
|
readonly docsSlug: string;
|
|
216
216
|
constructor(toolId: string, envVar: string, docsSlug: string);
|
|
217
217
|
}
|
|
218
|
+
/**
|
|
219
|
+
* Error thrown when an agent exceeds its budget/cost limit.
|
|
220
|
+
* Mirrors Python SDK: BudgetExceededError(agent_name, total_cost, max_budget)
|
|
221
|
+
*
|
|
222
|
+
* Usage:
|
|
223
|
+
* try { await agent.start("..."); }
|
|
224
|
+
* catch (e) {
|
|
225
|
+
* if (e instanceof BudgetExceededError)
|
|
226
|
+
* console.log(`Agent '${e.agentName}' spent $${e.totalCost} of $${e.maxBudget}`);
|
|
227
|
+
* }
|
|
228
|
+
*/
|
|
229
|
+
export declare class BudgetExceededError extends Error {
|
|
230
|
+
readonly agentName: string;
|
|
231
|
+
readonly totalCost: number;
|
|
232
|
+
readonly maxBudget: number;
|
|
233
|
+
constructor(agentName: string, totalCost: number, maxBudget: number);
|
|
234
|
+
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Standard interfaces for tool registration, execution, and middleware.
|
|
6
6
|
*/
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.MissingEnvVarError = exports.MissingDependencyError = void 0;
|
|
8
|
+
exports.BudgetExceededError = exports.MissingEnvVarError = exports.MissingDependencyError = void 0;
|
|
9
9
|
/**
|
|
10
10
|
* Error thrown when optional dependency is missing
|
|
11
11
|
*/
|
|
@@ -47,3 +47,24 @@ class MissingEnvVarError extends Error {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
exports.MissingEnvVarError = MissingEnvVarError;
|
|
50
|
+
/**
|
|
51
|
+
* Error thrown when an agent exceeds its budget/cost limit.
|
|
52
|
+
* Mirrors Python SDK: BudgetExceededError(agent_name, total_cost, max_budget)
|
|
53
|
+
*
|
|
54
|
+
* Usage:
|
|
55
|
+
* try { await agent.start("..."); }
|
|
56
|
+
* catch (e) {
|
|
57
|
+
* if (e instanceof BudgetExceededError)
|
|
58
|
+
* console.log(`Agent '${e.agentName}' spent $${e.totalCost} of $${e.maxBudget}`);
|
|
59
|
+
* }
|
|
60
|
+
*/
|
|
61
|
+
class BudgetExceededError extends Error {
|
|
62
|
+
constructor(agentName, totalCost, maxBudget) {
|
|
63
|
+
super(`Agent '${agentName}' exceeded budget: $${totalCost.toFixed(4)} >= $${maxBudget.toFixed(4)}`);
|
|
64
|
+
this.agentName = agentName;
|
|
65
|
+
this.totalCost = totalCost;
|
|
66
|
+
this.maxBudget = maxBudget;
|
|
67
|
+
this.name = 'BudgetExceededError';
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.BudgetExceededError = BudgetExceededError;
|
|
@@ -250,22 +250,52 @@ async function scrapeUrl(url) {
|
|
|
250
250
|
// ============================================================================
|
|
251
251
|
// UTILITY TOOLS
|
|
252
252
|
// ============================================================================
|
|
253
|
+
/** Shell metacharacters that enable command chaining or substitution */
|
|
254
|
+
const SHELL_METACHAR_PATTERN = /[;|&`><]|\$\([^)]*\)|\$\{/;
|
|
255
|
+
function containsShellMetacharacters(command) {
|
|
256
|
+
return SHELL_METACHAR_PATTERN.test(command);
|
|
257
|
+
}
|
|
258
|
+
function parseCommandParts(command) {
|
|
259
|
+
const parts = command.trim().match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g) ?? [];
|
|
260
|
+
return parts.map((part) => part.replace(/^["']|["']$/g, ''));
|
|
261
|
+
}
|
|
253
262
|
/**
|
|
254
263
|
* Execute shell command (safe version - read-only commands)
|
|
255
264
|
*/
|
|
256
265
|
async function shell(command) {
|
|
257
|
-
// Only allow safe read-only commands
|
|
258
266
|
const safeCommands = ['ls', 'cat', 'head', 'tail', 'wc', 'grep', 'find', 'echo', 'date', 'pwd', 'which'];
|
|
259
|
-
const
|
|
260
|
-
if (!
|
|
261
|
-
return { success: false, error:
|
|
267
|
+
const trimmed = command.trim();
|
|
268
|
+
if (!trimmed) {
|
|
269
|
+
return { success: false, error: 'Empty command' };
|
|
270
|
+
}
|
|
271
|
+
if (containsShellMetacharacters(trimmed)) {
|
|
272
|
+
return { success: false, error: 'Shell metacharacters are not allowed' };
|
|
273
|
+
}
|
|
274
|
+
const parts = parseCommandParts(trimmed);
|
|
275
|
+
const cmd = parts[0];
|
|
276
|
+
if (!safeCommands.includes(cmd)) {
|
|
277
|
+
return { success: false, error: `Command not allowed: ${cmd}` };
|
|
262
278
|
}
|
|
263
279
|
try {
|
|
264
|
-
const {
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
280
|
+
const { spawn } = await Promise.resolve().then(() => __importStar(require('child_process')));
|
|
281
|
+
const result = await new Promise((resolve, reject) => {
|
|
282
|
+
const proc = spawn(cmd, parts.slice(1), {
|
|
283
|
+
shell: false,
|
|
284
|
+
timeout: 5000,
|
|
285
|
+
});
|
|
286
|
+
let stdout = '';
|
|
287
|
+
let stderr = '';
|
|
288
|
+
proc.stdout?.on('data', (data) => { stdout += data.toString(); });
|
|
289
|
+
proc.stderr?.on('data', (data) => { stderr += data.toString(); });
|
|
290
|
+
proc.on('close', (code) => {
|
|
291
|
+
resolve({ stdout, stderr, code: code ?? 1 });
|
|
292
|
+
});
|
|
293
|
+
proc.on('error', reject);
|
|
294
|
+
});
|
|
295
|
+
if (result.code !== 0) {
|
|
296
|
+
return { success: false, error: result.stderr || `Exit code ${result.code}` };
|
|
297
|
+
}
|
|
298
|
+
return { success: true, data: result.stdout || result.stderr };
|
|
269
299
|
}
|
|
270
300
|
catch (error) {
|
|
271
301
|
return { success: false, error: error.message ?? String(error) };
|
|
@@ -41,7 +41,10 @@ export declare function createWorkflowFromYAML(definition: YAMLWorkflowDefinitio
|
|
|
41
41
|
/**
|
|
42
42
|
* Load workflow from YAML file
|
|
43
43
|
*/
|
|
44
|
-
export declare function loadWorkflowFromFile(filePath: string, agents?: Record<string, any>, tools?: Record<string, any
|
|
44
|
+
export declare function loadWorkflowFromFile(filePath: string, agents?: Record<string, any>, tools?: Record<string, any>, options?: {
|
|
45
|
+
basePath?: string;
|
|
46
|
+
maxFileSizeBytes?: number;
|
|
47
|
+
}): Promise<ParsedWorkflow>;
|
|
45
48
|
/**
|
|
46
49
|
* Validate YAML workflow definition
|
|
47
50
|
*/
|
|
@@ -42,12 +42,19 @@ exports.createWorkflowFromYAML = createWorkflowFromYAML;
|
|
|
42
42
|
exports.loadWorkflowFromFile = loadWorkflowFromFile;
|
|
43
43
|
exports.validateWorkflowDefinition = validateWorkflowDefinition;
|
|
44
44
|
const index_1 = require("./index");
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
// Whitelist of allowed step keys to prevent injection
|
|
47
|
+
const ALLOWED_STEP_KEYS = new Set([
|
|
48
|
+
'type', 'agent', 'tool', 'input', 'output', 'condition',
|
|
49
|
+
'onError', 'maxRetries', 'timeout', 'loopCondition', 'maxIterations',
|
|
50
|
+
]);
|
|
45
51
|
/**
|
|
46
52
|
* Parse YAML string into workflow definition
|
|
47
53
|
*/
|
|
48
54
|
function parseYAMLWorkflow(yamlContent) {
|
|
49
|
-
//
|
|
50
|
-
//
|
|
55
|
+
// SECURITY: If migrating to js-yaml, you MUST use:
|
|
56
|
+
// yaml.load(content, { schema: yaml.JSON_SCHEMA })
|
|
57
|
+
// Never use yaml.load() with DEFAULT_SCHEMA — it enables arbitrary JS execution.
|
|
51
58
|
const lines = yamlContent.split('\n');
|
|
52
59
|
const result = {
|
|
53
60
|
name: '',
|
|
@@ -90,7 +97,11 @@ function parseYAMLWorkflow(yamlContent) {
|
|
|
90
97
|
};
|
|
91
98
|
}
|
|
92
99
|
else if (currentStep) {
|
|
93
|
-
// Step properties
|
|
100
|
+
// Step properties — whitelist allowed keys to prevent injection
|
|
101
|
+
if (!ALLOWED_STEP_KEYS.has(key)) {
|
|
102
|
+
// Ignore unknown keys — do not allow arbitrary property injection
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
94
105
|
if (key === 'type')
|
|
95
106
|
currentStep.type = value;
|
|
96
107
|
else if (key === 'agent')
|
|
@@ -262,9 +273,35 @@ function parseValue(value) {
|
|
|
262
273
|
/**
|
|
263
274
|
* Load workflow from YAML file
|
|
264
275
|
*/
|
|
265
|
-
async function loadWorkflowFromFile(filePath, agents = {}, tools = {}) {
|
|
276
|
+
async function loadWorkflowFromFile(filePath, agents = {}, tools = {}, options = {}) {
|
|
266
277
|
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
|
|
267
|
-
|
|
278
|
+
// SECURITY: Prevent path traversal
|
|
279
|
+
const normalizedPath = path.normalize(filePath);
|
|
280
|
+
// Check for '..' as path segments (not just substring)
|
|
281
|
+
const pathSegments = normalizedPath.split(path.sep);
|
|
282
|
+
if (pathSegments.includes('..')) {
|
|
283
|
+
throw new Error('Path traversal detected: ".." path segments are not allowed');
|
|
284
|
+
}
|
|
285
|
+
let effectivePath;
|
|
286
|
+
// If basePath is specified, ensure resolvedPath stays within it
|
|
287
|
+
if (options.basePath) {
|
|
288
|
+
const resolvedBase = path.resolve(options.basePath);
|
|
289
|
+
const resolvedFile = path.resolve(options.basePath, normalizedPath);
|
|
290
|
+
if (!resolvedFile.startsWith(resolvedBase + path.sep) && resolvedFile !== resolvedBase) {
|
|
291
|
+
throw new Error(`File path must be within base directory: ${options.basePath}`);
|
|
292
|
+
}
|
|
293
|
+
effectivePath = resolvedFile;
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
effectivePath = path.resolve(normalizedPath);
|
|
297
|
+
}
|
|
298
|
+
// SECURITY: Enforce file size limit (default 1 MB)
|
|
299
|
+
const maxSize = options.maxFileSizeBytes ?? 1048576;
|
|
300
|
+
const stat = await fs.stat(effectivePath);
|
|
301
|
+
if (stat.size > maxSize) {
|
|
302
|
+
throw new Error(`File too large: ${stat.size} bytes exceeds limit of ${maxSize} bytes`);
|
|
303
|
+
}
|
|
304
|
+
const content = await fs.readFile(effectivePath, 'utf-8');
|
|
268
305
|
const definition = parseYAMLWorkflow(content);
|
|
269
306
|
return createWorkflowFromYAML(definition, agents, tools);
|
|
270
307
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "praisonai",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.2",
|
|
4
4
|
"description": "PraisonAI TypeScript AI Agents Framework - Node.js, npm, and Javascript AI Agents Framework",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
67
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
68
|
-
"axios": "
|
|
68
|
+
"axios": "1.8.4",
|
|
69
69
|
"dotenv": "^16.4.7",
|
|
70
70
|
"fast-xml-parser": "^4.5.1",
|
|
71
71
|
"node-fetch": "^2.6.9",
|