centient 3.2.0 → 3.2.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/utils/rlvr/python_executor.py +48 -141
- package/package.json +1 -1
|
@@ -2,19 +2,22 @@
|
|
|
2
2
|
"""
|
|
3
3
|
RLVR Python Sandbox Executor
|
|
4
4
|
|
|
5
|
-
Executes Python code in a restricted environment.
|
|
6
|
-
|
|
5
|
+
Executes Python code in a restricted environment using RestrictedPython.
|
|
6
|
+
RestrictedPython is REQUIRED - no fallback mode for security reasons.
|
|
7
7
|
|
|
8
8
|
Communication protocol:
|
|
9
9
|
- Reads JSON from stdin: {"code": "...", "input": ...}
|
|
10
10
|
- Writes JSON to stdout: {"status": "success|error|timeout", "returnValue": ..., "stdout": "...", "stderr": "..."}
|
|
11
11
|
|
|
12
12
|
Security measures:
|
|
13
|
+
- RestrictedPython compiler (required, no fallback)
|
|
13
14
|
- No file system access
|
|
14
15
|
- No network access
|
|
15
16
|
- No subprocess spawning
|
|
16
|
-
- No module imports
|
|
17
|
-
-
|
|
17
|
+
- No dangerous module imports
|
|
18
|
+
- Guarded attribute access (blocks __class__.__bases__ escape)
|
|
19
|
+
|
|
20
|
+
Install: pip install RestrictedPython
|
|
18
21
|
"""
|
|
19
22
|
|
|
20
23
|
import sys
|
|
@@ -24,130 +27,41 @@ import traceback
|
|
|
24
27
|
from contextlib import redirect_stdout, redirect_stderr
|
|
25
28
|
from typing import Any, Dict
|
|
26
29
|
|
|
27
|
-
#
|
|
30
|
+
# RestrictedPython is REQUIRED - no fallback mode
|
|
28
31
|
try:
|
|
29
32
|
from RestrictedPython import compile_restricted, safe_globals
|
|
30
33
|
from RestrictedPython.Guards import safe_builtins, guarded_iter_unpack_sequence
|
|
31
34
|
from RestrictedPython.Eval import default_guarded_getiter, default_guarded_getitem
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
'tuple': tuple,
|
|
47
|
-
'set': set,
|
|
48
|
-
'frozenset': frozenset,
|
|
49
|
-
'bytes': bytes,
|
|
50
|
-
'bytearray': bytearray,
|
|
51
|
-
|
|
52
|
-
# Type checking
|
|
53
|
-
'type': type,
|
|
54
|
-
'isinstance': isinstance,
|
|
55
|
-
'issubclass': issubclass,
|
|
56
|
-
|
|
57
|
-
# Math and numeric
|
|
58
|
-
'abs': abs,
|
|
59
|
-
'round': round,
|
|
60
|
-
'min': min,
|
|
61
|
-
'max': max,
|
|
62
|
-
'sum': sum,
|
|
63
|
-
'pow': pow,
|
|
64
|
-
'divmod': divmod,
|
|
65
|
-
|
|
66
|
-
# Iterables
|
|
67
|
-
'len': len,
|
|
68
|
-
'range': range,
|
|
69
|
-
'enumerate': enumerate,
|
|
70
|
-
'zip': zip,
|
|
71
|
-
'map': map,
|
|
72
|
-
'filter': filter,
|
|
73
|
-
'reversed': reversed,
|
|
74
|
-
'sorted': sorted,
|
|
75
|
-
'all': all,
|
|
76
|
-
'any': any,
|
|
77
|
-
|
|
78
|
-
# String/repr
|
|
79
|
-
'repr': repr,
|
|
80
|
-
'ascii': ascii,
|
|
81
|
-
'chr': chr,
|
|
82
|
-
'ord': ord,
|
|
83
|
-
'bin': bin,
|
|
84
|
-
'hex': hex,
|
|
85
|
-
'oct': oct,
|
|
86
|
-
'format': format,
|
|
87
|
-
|
|
88
|
-
# Object inspection (safe subset)
|
|
89
|
-
'hasattr': hasattr,
|
|
90
|
-
'getattr': getattr,
|
|
91
|
-
'callable': callable,
|
|
92
|
-
'id': id,
|
|
93
|
-
'hash': hash,
|
|
94
|
-
|
|
95
|
-
# Exceptions
|
|
96
|
-
'Exception': Exception,
|
|
97
|
-
'ValueError': ValueError,
|
|
98
|
-
'TypeError': TypeError,
|
|
99
|
-
'KeyError': KeyError,
|
|
100
|
-
'IndexError': IndexError,
|
|
101
|
-
'AttributeError': AttributeError,
|
|
102
|
-
'RuntimeError': RuntimeError,
|
|
103
|
-
'StopIteration': StopIteration,
|
|
104
|
-
'ZeroDivisionError': ZeroDivisionError,
|
|
105
|
-
|
|
106
|
-
# Constants
|
|
107
|
-
'True': True,
|
|
108
|
-
'False': False,
|
|
109
|
-
'None': None,
|
|
110
|
-
|
|
111
|
-
# Print (captured)
|
|
112
|
-
'print': print,
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
# Explicitly blocked - should NOT be available
|
|
116
|
-
BLOCKED = {
|
|
117
|
-
'open', 'file', 'input', 'raw_input',
|
|
118
|
-
'exec', 'eval', 'compile',
|
|
119
|
-
'__import__', 'import',
|
|
120
|
-
'globals', 'locals', 'vars', 'dir',
|
|
121
|
-
'setattr', 'delattr',
|
|
122
|
-
'exit', 'quit',
|
|
123
|
-
'help', 'license', 'credits', 'copyright',
|
|
124
|
-
}
|
|
35
|
+
except ImportError as e:
|
|
36
|
+
# Fatal error - RestrictedPython is required for security
|
|
37
|
+
print(json.dumps({
|
|
38
|
+
'status': 'error',
|
|
39
|
+
'returnValue': None,
|
|
40
|
+
'stdout': '',
|
|
41
|
+
'stderr': '',
|
|
42
|
+
'error': {
|
|
43
|
+
'type': 'SecurityError',
|
|
44
|
+
'message': 'RestrictedPython is required but not installed. '
|
|
45
|
+
'Install with: pip install RestrictedPython',
|
|
46
|
+
},
|
|
47
|
+
}))
|
|
48
|
+
sys.exit(1)
|
|
125
49
|
|
|
126
50
|
|
|
127
51
|
def create_safe_globals(input_value: Any) -> Dict[str, Any]:
|
|
128
|
-
"""Create a restricted global namespace for code execution."""
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
restricted_globals['print'] = print # Allow print for output capture
|
|
138
|
-
return restricted_globals
|
|
139
|
-
else:
|
|
140
|
-
# Use our restricted builtins
|
|
141
|
-
return {
|
|
142
|
-
'__builtins__': SAFE_BUILTINS,
|
|
143
|
-
'__name__': '__restricted__',
|
|
144
|
-
'__doc__': None,
|
|
145
|
-
'__INPUT__': input_value,
|
|
146
|
-
}
|
|
52
|
+
"""Create a restricted global namespace for code execution using RestrictedPython."""
|
|
53
|
+
restricted_globals = dict(safe_globals)
|
|
54
|
+
restricted_globals['__builtins__'] = safe_builtins
|
|
55
|
+
restricted_globals['_getiter_'] = default_guarded_getiter
|
|
56
|
+
restricted_globals['_getitem_'] = default_guarded_getitem
|
|
57
|
+
restricted_globals['_iter_unpack_sequence_'] = guarded_iter_unpack_sequence
|
|
58
|
+
restricted_globals['__INPUT__'] = input_value
|
|
59
|
+
restricted_globals['print'] = print # Allow print for output capture
|
|
60
|
+
return restricted_globals
|
|
147
61
|
|
|
148
62
|
|
|
149
63
|
def execute_code(code: str, input_value: Any) -> Dict[str, Any]:
|
|
150
|
-
"""Execute code in restricted environment
|
|
64
|
+
"""Execute code in restricted environment using RestrictedPython."""
|
|
151
65
|
stdout_capture = io.StringIO()
|
|
152
66
|
stderr_capture = io.StringIO()
|
|
153
67
|
|
|
@@ -157,34 +71,27 @@ def execute_code(code: str, input_value: Any) -> Dict[str, Any]:
|
|
|
157
71
|
'stdout': '',
|
|
158
72
|
'stderr': '',
|
|
159
73
|
'error': None,
|
|
160
|
-
'restrictedMode': 'RestrictedPython'
|
|
74
|
+
'restrictedMode': 'RestrictedPython',
|
|
161
75
|
}
|
|
162
76
|
|
|
163
77
|
try:
|
|
164
78
|
# Create safe globals
|
|
165
79
|
safe_globals_dict = create_safe_globals(input_value)
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
}
|
|
182
|
-
return result
|
|
183
|
-
compiled_code = byte_code.code
|
|
184
|
-
else:
|
|
185
|
-
# Standard compile with AST validation would go here
|
|
186
|
-
# For now, just compile normally (relies on restricted builtins)
|
|
187
|
-
compiled_code = compile(code, '<pattern>', 'exec')
|
|
80
|
+
|
|
81
|
+
# Compile code with RestrictedPython
|
|
82
|
+
byte_code = compile_restricted(
|
|
83
|
+
code,
|
|
84
|
+
filename='<pattern>',
|
|
85
|
+
mode='exec'
|
|
86
|
+
)
|
|
87
|
+
if byte_code.errors:
|
|
88
|
+
result['status'] = 'error'
|
|
89
|
+
result['error'] = {
|
|
90
|
+
'type': 'CompilationError',
|
|
91
|
+
'message': '\n'.join(byte_code.errors),
|
|
92
|
+
}
|
|
93
|
+
return result
|
|
94
|
+
compiled_code = byte_code.code
|
|
188
95
|
|
|
189
96
|
# Execute with output capture
|
|
190
97
|
# Use same dict for globals and locals to enable recursive functions
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "centient",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.2",
|
|
4
4
|
"description": "MCP server for context engineering operations with handoff protocol, health monitoring, session branching with visualization, and query-based artifact loading",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|