claude-flow
Version:
Ruflo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration
94 lines • 3.77 kB
JavaScript
/**
* GAIA Tool: python_exec — DAG actor catalogue (iter-65 Fix 1)
*
* Executes a Python script in a sandboxed subprocess and returns stdout.
* Designed for use by DAG actors that need to simulate probabilities,
* run numeric computations, or process data programmatically.
*
* Security:
* - Code is passed via stdin (not shell args) to avoid injection.
* - Hard timeout: 30 seconds.
* - No network access inside the script (subprocess environment is the
* same user-level Python, not a full sandbox — adequate for GAIA L1
* computations which are math/logic only, not I/O heavy).
*
* Input schema:
* code — Python source to execute (passed via stdin to python3 -)
*
* Output:
* stdout of the script, trimmed.
* On non-zero exit or timeout, returns a descriptive error string.
*
* Refs: ADR-139, iter-65, #2156
*/
import { execFileSync } from 'node:child_process';
// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------
const PYTHON_EXEC_TIMEOUT_MS = 30_000;
const PYTHON_OUTPUT_MAX_CHARS = 4_000;
// ---------------------------------------------------------------------------
// PythonExecTool
// ---------------------------------------------------------------------------
export class PythonExecTool {
name = 'python_exec';
definition = {
name: 'python_exec',
description: 'Execute a Python 3 script and return its stdout output. ' +
'Use this for mathematical calculations, probability simulations, ' +
'data processing, or any computation that requires running Python code. ' +
'The code is passed via stdin to python3. ' +
'Print your result to stdout. ' +
'Timeout: 30 seconds. Maximum output: 4000 characters.',
input_schema: {
type: 'object',
properties: {
code: {
type: 'string',
description: 'Python 3 source code to execute. Use print() to output results.',
},
},
required: ['code'],
},
};
async execute(input) {
const code = String(input['code'] ?? '').trim();
if (!code) {
return 'python_exec: empty code — nothing to execute.';
}
let stdout;
try {
stdout = execFileSync('python3', ['-'], {
input: code,
encoding: 'utf-8',
timeout: PYTHON_EXEC_TIMEOUT_MS,
}).trim();
}
catch (err) {
if (err instanceof Error) {
// Include stderr in the error output so actors can diagnose
const spawnErr = err;
const stderr = String(spawnErr.stderr ?? '').trim();
const partial = String(spawnErr.stdout ?? '').trim();
const parts = [`python_exec error: ${err.message}`];
if (stderr)
parts.push(`stderr: ${stderr.slice(0, 1000)}`);
if (partial)
parts.push(`partial stdout: ${partial.slice(0, 500)}`);
return parts.join('\n');
}
return `python_exec error: ${String(err)}`;
}
if (!stdout) {
return '(no output — script produced no stdout)';
}
return stdout.slice(0, PYTHON_OUTPUT_MAX_CHARS);
}
}
// ---------------------------------------------------------------------------
// Convenience factory
// ---------------------------------------------------------------------------
export function createPythonExecTool() {
return new PythonExecTool();
}
//# sourceMappingURL=python_exec.js.map