UNPKG

mcard-js

Version:

MCard - Content-addressable storage with cryptographic hashing, handle resolution, and vector search for Node.js and browsers

100 lines (94 loc) 3.06 kB
/** * Python runtime executor. * * Executes Python code via subprocess with automatic entry point detection. */ import * as fs from 'fs'; import * as path from 'path'; import * as util from 'util'; import { execFile, parseOutput } from './base.js'; import { findProjectRoot } from '../FileSystemUtils.js'; const writeFile = util.promisify(fs.writeFile); const unlink = util.promisify(fs.unlink); export class PythonRuntime { async execute(code, context, config) { const entryPoint = config.entry_point || 'add'; const contextStr = JSON.stringify(context); const projectRoot = findProjectRoot(); const wrapper = this.createWrapper(code, entryPoint); const tmpFile = path.resolve(process.cwd(), `tmp_${Date.now()}.py`); await writeFile(tmpFile, wrapper); try { const { stdout, stderr } = await execFile('python3', [tmpFile, contextStr], { cwd: projectRoot, env: { ...process.env, PYTHONPATH: `${projectRoot}${path.delimiter}${process.env.PYTHONPATH || ''}` } }); if (stderr) console.error('[Python Stderr]', stderr); return parseOutput(stdout); } catch (error) { const stderr = error.stderr ? `\nStderr: ${error.stderr.toString()}` : ''; const stdout = error.stdout ? `\nStdout: ${error.stdout.toString()}` : ''; throw new Error(`Python execution failed: ${error.message}${stderr}${stdout}`); } finally { await unlink(tmpFile); } } /** * Create Python wrapper script with entry point invocation. */ createWrapper(code, entryPoint) { return ` import sys import json try: context = json.loads(sys.argv[1]) target = context if isinstance(target, str): target = target.encode('utf-8') except: context = {} target = {} pass # User logic ${code} # Entry point invocation def _is_arg_error(e): msg = str(e).lower() return 'positional argument' in msg or 'required argument' in msg or 'takes' in msg and 'argument' in msg try: fn = None if '${entryPoint}' in dir(): fn = ${entryPoint} elif '${entryPoint}' in globals(): fn = globals()['${entryPoint}'] if fn is not None: try: res = fn(context) except TypeError as e: if not _is_arg_error(e): raise try: res = fn(target) except TypeError as e2: if not _is_arg_error(e2): raise res = fn() print(json.dumps(res)) else: if 'result' in dir() or 'result' in globals(): print(json.dumps(result if 'result' in dir() else globals().get('result'))) else: print(json.dumps(None)) except Exception as e: print(json.dumps({"error": str(e)})) sys.exit(1) `; } } //# sourceMappingURL=python.js.map