Spaces:
Sleeping
Sleeping
extend code eval
Browse files- app.py +9 -4
- code_exec.py +137 -4
app.py
CHANGED
@@ -46,14 +46,19 @@ def bot(message, history, aws_access, aws_secret, aws_token, system_prompt, temp
|
|
46 |
"tools": [{
|
47 |
"toolSpec": {
|
48 |
"name": "eval_python",
|
49 |
-
"description": "Evaluate
|
|
|
|
|
|
|
50 |
"inputSchema": {
|
51 |
"json": {
|
52 |
"type": "object",
|
53 |
"properties": {
|
54 |
"script": {
|
55 |
"type": "string",
|
56 |
-
"description": "The Python script that will run in a RestrictedPython context"
|
|
|
|
|
57 |
}
|
58 |
},
|
59 |
"required": ["script"]
|
@@ -111,13 +116,13 @@ def bot(message, history, aws_access, aws_secret, aws_token, system_prompt, temp
|
|
111 |
{
|
112 |
"toolResult": {
|
113 |
"toolUseId": tool['toolUseId'],
|
114 |
-
"content": [{"json": tool_result}]
|
115 |
}
|
116 |
}
|
117 |
]
|
118 |
}
|
119 |
|
120 |
-
whole_response += f"\n``` result\n{tool_result}\n```\n"
|
121 |
yield whole_response
|
122 |
except Exception as e:
|
123 |
tool_result_message = {
|
|
|
46 |
"tools": [{
|
47 |
"toolSpec": {
|
48 |
"name": "eval_python",
|
49 |
+
"description": "Evaluate a simple script written in a conservative, restricted subset of Python."
|
50 |
+
"Note: Augmented assignments, in-place operations (e.g., +=, -=), lambdas (e.g. list comprehensions) are not supported. "
|
51 |
+
"Use regular assignments and operations instead. Only 'import math' is allowed. "
|
52 |
+
"Returns: unquoted results without HTML encoding.",
|
53 |
"inputSchema": {
|
54 |
"json": {
|
55 |
"type": "object",
|
56 |
"properties": {
|
57 |
"script": {
|
58 |
"type": "string",
|
59 |
+
"description": "The Python script that will run in a RestrictedPython context. "
|
60 |
+
"Avoid using augmented assignments or in-place operations (+=, -=, etc.), as well as lambdas (e.g. list comprehensions). "
|
61 |
+
"Use regular assignments and operations instead. Only 'import math' is allowed."
|
62 |
}
|
63 |
},
|
64 |
"required": ["script"]
|
|
|
116 |
{
|
117 |
"toolResult": {
|
118 |
"toolUseId": tool['toolUseId'],
|
119 |
+
"content": [{"json": tool_result }]
|
120 |
}
|
121 |
}
|
122 |
]
|
123 |
}
|
124 |
|
125 |
+
whole_response += f"\n``` result\n{tool_result if not tool_result['success'] else tool_result['prints']}\n```\n"
|
126 |
yield whole_response
|
127 |
except Exception as e:
|
128 |
tool_result_message = {
|
code_exec.py
CHANGED
@@ -1,8 +1,10 @@
|
|
1 |
from RestrictedPython import compile_restricted
|
2 |
from RestrictedPython.PrintCollector import PrintCollector
|
3 |
from RestrictedPython.Guards import safe_globals, safe_builtins, guarded_iter_unpack_sequence
|
4 |
-
from RestrictedPython.Eval import default_guarded_getiter
|
5 |
from RestrictedPython.Utilities import utility_builtins
|
|
|
|
|
6 |
from io import StringIO
|
7 |
|
8 |
def eval_restricted_script(script):
|
@@ -39,8 +41,13 @@ def eval_restricted_script(script):
|
|
39 |
# Print handling
|
40 |
'_print_': CustomPrintCollector,
|
41 |
'_getattr_': getattr,
|
|
|
42 |
'_getiter_': default_guarded_getiter,
|
43 |
'_iter_unpack_sequence_': guarded_iter_unpack_sequence,
|
|
|
|
|
|
|
|
|
44 |
|
45 |
# Define allowed imports
|
46 |
'__allowed_modules__': ['math'],
|
@@ -48,7 +55,7 @@ def eval_restricted_script(script):
|
|
48 |
|
49 |
# Basic functions
|
50 |
'len': len,
|
51 |
-
'range':
|
52 |
'enumerate': enumerate,
|
53 |
'zip': zip,
|
54 |
|
@@ -65,8 +72,8 @@ def eval_restricted_script(script):
|
|
65 |
'float': float,
|
66 |
'str': str,
|
67 |
'bool': bool,
|
68 |
-
'list':
|
69 |
-
'tuple':
|
70 |
'set': set,
|
71 |
'dict': dict,
|
72 |
'bytes': bytes,
|
@@ -107,3 +114,129 @@ def eval_restricted_script(script):
|
|
107 |
'error': str(e),
|
108 |
'success': False
|
109 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
from RestrictedPython import compile_restricted
|
2 |
from RestrictedPython.PrintCollector import PrintCollector
|
3 |
from RestrictedPython.Guards import safe_globals, safe_builtins, guarded_iter_unpack_sequence
|
4 |
+
from RestrictedPython.Eval import default_guarded_getiter, default_guarded_getitem
|
5 |
from RestrictedPython.Utilities import utility_builtins
|
6 |
+
from RestrictedPython.Guards import guarded_unpack_sequence
|
7 |
+
from RestrictedPython.Limits import limited_range, limited_list, limited_tuple
|
8 |
from io import StringIO
|
9 |
|
10 |
def eval_restricted_script(script):
|
|
|
41 |
# Print handling
|
42 |
'_print_': CustomPrintCollector,
|
43 |
'_getattr_': getattr,
|
44 |
+
'_getitem_': default_guarded_getitem,
|
45 |
'_getiter_': default_guarded_getiter,
|
46 |
'_iter_unpack_sequence_': guarded_iter_unpack_sequence,
|
47 |
+
'_unpack_sequence_': guarded_unpack_sequence,
|
48 |
+
'_inplacevar_': protected_inplacevar,
|
49 |
+
'_apply_': _apply,
|
50 |
+
'_write_': _default_write_,
|
51 |
|
52 |
# Define allowed imports
|
53 |
'__allowed_modules__': ['math'],
|
|
|
55 |
|
56 |
# Basic functions
|
57 |
'len': len,
|
58 |
+
'range': limited_range,
|
59 |
'enumerate': enumerate,
|
60 |
'zip': zip,
|
61 |
|
|
|
72 |
'float': float,
|
73 |
'str': str,
|
74 |
'bool': bool,
|
75 |
+
'list': limited_list,
|
76 |
+
'tuple': limited_tuple,
|
77 |
'set': set,
|
78 |
'dict': dict,
|
79 |
'bytes': bytes,
|
|
|
114 |
'error': str(e),
|
115 |
'success': False
|
116 |
}
|
117 |
+
|
118 |
+
def _default_write_(obj):
|
119 |
+
if isinstance(obj, types.ModuleType):
|
120 |
+
raise ValueError("Modules are not allowed in to be written to.")
|
121 |
+
|
122 |
+
return obj
|
123 |
+
|
124 |
+
"""
|
125 |
+
Borrowed implementation of _inplacevar_ from the Zope Foundations's AccessControl module
|
126 |
+
https://github.com/zopefoundation/AccessControl/blob/f9ae58816f0712eb6ea97459b4ccafbf4662d9db/src/AccessControl/ZopeGuards.py#L530
|
127 |
+
"""
|
128 |
+
|
129 |
+
valid_inplace_types = (list, set)
|
130 |
+
|
131 |
+
|
132 |
+
inplace_slots = {
|
133 |
+
'+=': '__iadd__',
|
134 |
+
'-=': '__isub__',
|
135 |
+
'*=': '__imul__',
|
136 |
+
'/=': (1 / 2 == 0) and '__idiv__' or '__itruediv__',
|
137 |
+
'//=': '__ifloordiv__',
|
138 |
+
'%=': '__imod__',
|
139 |
+
'**=': '__ipow__',
|
140 |
+
'<<=': '__ilshift__',
|
141 |
+
'>>=': '__irshift__',
|
142 |
+
'&=': '__iand__',
|
143 |
+
'^=': '__ixor__',
|
144 |
+
'|=': '__ior__',
|
145 |
+
}
|
146 |
+
|
147 |
+
|
148 |
+
def __iadd__(x, y):
|
149 |
+
x += y
|
150 |
+
return x
|
151 |
+
|
152 |
+
|
153 |
+
def __isub__(x, y):
|
154 |
+
x -= y
|
155 |
+
return x
|
156 |
+
|
157 |
+
|
158 |
+
def __imul__(x, y):
|
159 |
+
x *= y
|
160 |
+
return x
|
161 |
+
|
162 |
+
|
163 |
+
def __idiv__(x, y):
|
164 |
+
x /= y
|
165 |
+
return x
|
166 |
+
|
167 |
+
|
168 |
+
def __ifloordiv__(x, y):
|
169 |
+
x //= y
|
170 |
+
return x
|
171 |
+
|
172 |
+
|
173 |
+
def __imod__(x, y):
|
174 |
+
x %= y
|
175 |
+
return x
|
176 |
+
|
177 |
+
|
178 |
+
def __ipow__(x, y):
|
179 |
+
x **= y
|
180 |
+
return x
|
181 |
+
|
182 |
+
|
183 |
+
def __ilshift__(x, y):
|
184 |
+
x <<= y
|
185 |
+
return x
|
186 |
+
|
187 |
+
|
188 |
+
def __irshift__(x, y):
|
189 |
+
x >>= y
|
190 |
+
return x
|
191 |
+
|
192 |
+
|
193 |
+
def __iand__(x, y):
|
194 |
+
x &= y
|
195 |
+
return x
|
196 |
+
|
197 |
+
|
198 |
+
def __ixor__(x, y):
|
199 |
+
x ^= y
|
200 |
+
return x
|
201 |
+
|
202 |
+
|
203 |
+
def __ior__(x, y):
|
204 |
+
x |= y
|
205 |
+
return x
|
206 |
+
|
207 |
+
|
208 |
+
inplace_ops = {
|
209 |
+
'+=': __iadd__,
|
210 |
+
'-=': __isub__,
|
211 |
+
'*=': __imul__,
|
212 |
+
'/=': __idiv__,
|
213 |
+
'//=': __ifloordiv__,
|
214 |
+
'%=': __imod__,
|
215 |
+
'**=': __ipow__,
|
216 |
+
'<<=': __ilshift__,
|
217 |
+
'>>=': __irshift__,
|
218 |
+
'&=': __iand__,
|
219 |
+
'^=': __ixor__,
|
220 |
+
'|=': __ior__,
|
221 |
+
}
|
222 |
+
|
223 |
+
|
224 |
+
def protected_inplacevar(op, var, expr):
|
225 |
+
"""Do an inplace operation
|
226 |
+
|
227 |
+
If the var has an inplace slot, then disallow the operation
|
228 |
+
unless the var an instance of ``valid_inplace_types``.
|
229 |
+
"""
|
230 |
+
if hasattr(var, inplace_slots[op]) and \
|
231 |
+
not isinstance(var, valid_inplace_types):
|
232 |
+
try:
|
233 |
+
cls = var.__class__
|
234 |
+
except AttributeError:
|
235 |
+
cls = type(var)
|
236 |
+
raise TypeError(
|
237 |
+
"Augmented assignment to %s objects is not allowed"
|
238 |
+
" in untrusted code" % cls.__name__)
|
239 |
+
return inplace_ops[op](var, expr)
|
240 |
+
|
241 |
+
def _apply(f, *a, **kw):
|
242 |
+
return f(*a, **kw)
|