Noodle-bg commited on
Commit
531f682
1 Parent(s): fe4a3b4

Upload tool

Browse files
Files changed (4) hide show
  1. app.py +4 -0
  2. python_tool.py +84 -0
  3. requirements.txt +6 -0
  4. tool_config.json +7 -0
app.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ from transformers import launch_gradio_demo
2
+ from python_tool import PythonExecutorToolWithInputs
3
+
4
+ launch_gradio_demo(PythonExecutorToolWithInputs)
python_tool.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import Tool
2
+ import ast
3
+ import io
4
+ import sys
5
+ from contextlib import redirect_stdout
6
+ import importlib
7
+
8
+ class PythonExecutorToolWithInputs(Tool):
9
+ name = "python_executor_with_test_inputs"
10
+ description = (
11
+ "This tool executes Python code with given inputs. It takes a single input containing:"
12
+ "1. Python code to execute."
13
+ "2. A line containing only '#inputs' (without quotes)."
14
+ "3. Input values, one per line, to be used when the code calls input()."
15
+ "For example if there are 2 input funtion calls in the code with first taking 2 arguments and second taking 1:"
16
+ "12 43\n94"
17
+ "The tool returns the outputs(if multiple or else single) of the executed code as a string."
18
+ )
19
+ inputs = ["text"]
20
+ outputs = ["text"]
21
+
22
+ def __call__(self, task: str):
23
+ # Split code and inputs
24
+ parts = task.split('#inputs')
25
+ if len(parts) != 2:
26
+ return "Error: Input must contain '#inputs' separator."
27
+
28
+ code = parts[0].strip()
29
+ inputss = parts[1].strip().split('\n')
30
+ input_iterator = iter(inputss)
31
+
32
+ def safe_input():
33
+ try:
34
+ return next(input_iterator)
35
+ except StopIteration:
36
+ raise EOFError("No more input available")
37
+
38
+ # Set up a safe environment for code execution
39
+ safe_globals = {
40
+ 'print': print,
41
+ 'input': safe_input,
42
+ 'len': len,
43
+ 'int': int,
44
+ 'float': float,
45
+ 'str': str,
46
+ 'list': list,
47
+ 'dict': dict,
48
+ 'set': set,
49
+ 'tuple': tuple,
50
+ 'range': range,
51
+ 'enumerate': enumerate,
52
+ 'zip': zip,
53
+ 'sum': sum,
54
+ 'min': min,
55
+ 'max': max,
56
+ 'abs': abs,
57
+ 'round': round,
58
+ }
59
+
60
+ # Pre-import allowed modules
61
+ allowed_modules = ['math', 'random', 'datetime', 're','numpy','pandas']
62
+ for module_name in allowed_modules:
63
+ try:
64
+ module = importlib.import_module(module_name)
65
+ safe_globals[module_name] = module
66
+ except ImportError:
67
+ pass # Skip if module is not available
68
+
69
+ # Capture stdout
70
+ output_buffer = io.StringIO()
71
+
72
+ try:
73
+ # Parse the code to check for syntax errors
74
+ ast.parse(code)
75
+
76
+ # Execute the code
77
+ with redirect_stdout(output_buffer):
78
+ exec(code, safe_globals)
79
+
80
+ output = output_buffer.getvalue()
81
+ except Exception as e:
82
+ output = f"Error: {str(e)}"
83
+
84
+ return output
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ sys
2
+ importlib
3
+ io
4
+ ast
5
+ transformers
6
+ contextlib
tool_config.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "description": "This tool executes Python code with given inputs. It takes a single input containing:1. Python code to execute.2. A line containing only '#inputs' (without quotes).3. Input values, one per line, to be used when the code calls input().For example if there are 2 input funtion calls in the code with first taking 2 arguments and second taking 1:12 43\n94The tool returns the outputs(if multiple or else single) of the executed code as a string.",
3
+ "inputs": "['text']",
4
+ "name": "python_executor_with_test_inputs",
5
+ "output_type": "<class 'str'>",
6
+ "tool_class": "python_tool.PythonExecutorToolWithInputs"
7
+ }