Update app.py
Browse files
app.py
CHANGED
@@ -2,33 +2,67 @@ from flask import Flask, request, jsonify, render_template, send_from_directory
|
|
2 |
import os
|
3 |
import subprocess
|
4 |
import tempfile
|
|
|
|
|
5 |
import google.generativeai as genai
|
6 |
|
7 |
app = Flask(__name__)
|
|
|
|
|
8 |
temp_dir = tempfile.mkdtemp()
|
9 |
current_dir = temp_dir
|
10 |
|
11 |
-
# Configure
|
12 |
genai.configure(api_key=os.environ["GEMINI_API_KEY"])
|
13 |
|
14 |
-
# Create the model
|
15 |
generation_config = {
|
16 |
-
"temperature":
|
17 |
-
"top_p":
|
18 |
-
"top_k":
|
19 |
-
"max_output_tokens":
|
20 |
-
"response_mime_type": "text/plain",
|
21 |
}
|
22 |
|
23 |
model = genai.GenerativeModel(
|
24 |
-
model_name="gemini-
|
25 |
generation_config=generation_config,
|
26 |
-
system_instruction="You are an AGI assistant. Follow these rules:\n1. Respond with executable code when asked to create files\n2. Use Python code blocks for scripts\n3. Use bash code blocks for terminal commands\n4. Keep responses concise and actionable"
|
27 |
)
|
28 |
|
29 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
|
31 |
def execute_command(command, cwd=None):
|
|
|
32 |
process = subprocess.Popen(
|
33 |
command,
|
34 |
shell=True,
|
@@ -40,65 +74,127 @@ def execute_command(command, cwd=None):
|
|
40 |
stdout, stderr = process.communicate()
|
41 |
return stdout + stderr
|
42 |
|
|
|
|
|
|
|
|
|
|
|
43 |
@app.route("/")
|
44 |
def index():
|
45 |
return render_template("index.html")
|
46 |
|
47 |
-
def handle_code_response(response):
|
48 |
-
python_code = []
|
49 |
-
for part in response.parts:
|
50 |
-
if "```python" in part.text:
|
51 |
-
code = part.text.split("```python")[1].split("```")[0].strip()
|
52 |
-
python_code.append(code)
|
53 |
-
return python_code
|
54 |
-
|
55 |
@app.route("/execute", methods=["POST"])
|
56 |
def execute_code():
|
|
|
57 |
command = request.json.get("code", "").strip()
|
58 |
if not command:
|
59 |
return jsonify({"result": "Error: No command provided."})
|
60 |
|
61 |
try:
|
62 |
-
if command.lower().startswith(
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
elif command.startswith("!"):
|
92 |
result = execute_command(command[1:])
|
93 |
-
|
94 |
-
|
|
|
|
|
95 |
else:
|
96 |
-
|
97 |
-
|
|
|
|
|
|
|
98 |
except Exception as e:
|
99 |
-
return jsonify({"result": f"Error: {str(e)}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
|
101 |
-
@app.route("/download/<path:filename>")
|
102 |
def download_file(filename):
|
103 |
return send_from_directory(current_dir, filename, as_attachment=True)
|
104 |
|
|
|
2 |
import os
|
3 |
import subprocess
|
4 |
import tempfile
|
5 |
+
import shutil
|
6 |
+
import sys
|
7 |
import google.generativeai as genai
|
8 |
|
9 |
app = Flask(__name__)
|
10 |
+
|
11 |
+
# Create a temporary directory for operations
|
12 |
temp_dir = tempfile.mkdtemp()
|
13 |
current_dir = temp_dir
|
14 |
|
15 |
+
# Configure Gemini AI
|
16 |
genai.configure(api_key=os.environ["GEMINI_API_KEY"])
|
17 |
|
|
|
18 |
generation_config = {
|
19 |
+
"temperature": 0.9,
|
20 |
+
"top_p": 1,
|
21 |
+
"top_k": 40,
|
22 |
+
"max_output_tokens": 1024,
|
|
|
23 |
}
|
24 |
|
25 |
model = genai.GenerativeModel(
|
26 |
+
model_name="gemini-1.5-pro",
|
27 |
generation_config=generation_config,
|
|
|
28 |
)
|
29 |
|
30 |
+
system_instruction = """
|
31 |
+
You are an AI-powered terminal assistant. Your role is to interpret user requests and execute appropriate terminal commands or actions. Follow these guidelines:
|
32 |
+
|
33 |
+
1. Understand and execute various commands, including but not limited to:
|
34 |
+
- pip install: For installing Python packages
|
35 |
+
- git clone: For cloning repositories
|
36 |
+
- cd: For changing directories
|
37 |
+
- Python script execution: For running .py files
|
38 |
+
- File creation and editing: For creating new files and adding content
|
39 |
+
|
40 |
+
2. Provide the exact command(s) to be executed or action(s) to be taken, without any explanation or additional text.
|
41 |
+
|
42 |
+
3. For pip install requests, always prefix the command with '!python -m' to ensure proper execution.
|
43 |
+
|
44 |
+
4. For git clone requests, provide the full 'git clone' command with the repository URL.
|
45 |
+
|
46 |
+
5. For cd requests, simply provide the 'cd' command with the specified directory.
|
47 |
+
|
48 |
+
6. For Python script execution, provide the command to run the script (e.g., '!python script_name.py').
|
49 |
+
|
50 |
+
7. For file creation and editing requests:
|
51 |
+
- If asked to create a new file, respond with: "CREATE_FILE:filename.py"
|
52 |
+
- If asked to edit a file with specific content, respond with: "EDIT_FILE:filename.py:file_content"
|
53 |
+
Replace 'filename.py' with the actual filename and 'file_content' with the requested content.
|
54 |
+
|
55 |
+
8. If a request requires multiple commands, provide them as a list of commands, each on a new line, prefixed with 'CMD:'.
|
56 |
+
|
57 |
+
9. If a request is unclear or doesn't match any known command type, respond with "Unclear request. Please provide more details."
|
58 |
+
|
59 |
+
Always respond with ONLY the command(s) to be executed or action(s) to be taken, nothing else.
|
60 |
+
"""
|
61 |
+
|
62 |
+
chat = model.start_chat(history=[])
|
63 |
|
64 |
def execute_command(command, cwd=None):
|
65 |
+
"""Executes a command and returns the output."""
|
66 |
process = subprocess.Popen(
|
67 |
command,
|
68 |
shell=True,
|
|
|
74 |
stdout, stderr = process.communicate()
|
75 |
return stdout + stderr
|
76 |
|
77 |
+
def read_knowledge_base():
|
78 |
+
knowledge_file = os.path.join(os.path.dirname(__file__), 'knowledge.txt')
|
79 |
+
with open(knowledge_file, 'r') as file:
|
80 |
+
return file.read()
|
81 |
+
|
82 |
@app.route("/")
|
83 |
def index():
|
84 |
return render_template("index.html")
|
85 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
@app.route("/execute", methods=["POST"])
|
87 |
def execute_code():
|
88 |
+
global current_dir
|
89 |
command = request.json.get("code", "").strip()
|
90 |
if not command:
|
91 |
return jsonify({"result": "Error: No command provided."})
|
92 |
|
93 |
try:
|
94 |
+
if command.lower().startswith("ai:"):
|
95 |
+
# Process command with Gemini AI
|
96 |
+
ai_command = command[3:].strip()
|
97 |
+
knowledge_base = read_knowledge_base()
|
98 |
+
response = chat.send_message(f"{system_instruction}\n\nKnowledge Base:\n{knowledge_base}\n\nUser request: {ai_command}")
|
99 |
+
ai_result = response.text.strip()
|
100 |
+
|
101 |
+
# Split multiple commands
|
102 |
+
commands = [cmd.strip() for cmd in ai_result.split('CMD:') if cmd.strip()]
|
103 |
+
results = []
|
104 |
+
|
105 |
+
for cmd in commands:
|
106 |
+
if cmd.startswith("CREATE_FILE:"):
|
107 |
+
filename = cmd.split(":")[1]
|
108 |
+
filepath = os.path.join(current_dir, filename)
|
109 |
+
with open(filepath, 'w') as f:
|
110 |
+
pass # Create an empty file
|
111 |
+
results.append(f"Created new file: {filename}")
|
112 |
+
elif cmd.startswith("EDIT_FILE:"):
|
113 |
+
_, filename, content = cmd.split(":", 2)
|
114 |
+
filepath = os.path.join(current_dir, filename)
|
115 |
+
with open(filepath, 'w') as f:
|
116 |
+
f.write(content)
|
117 |
+
results.append(f"File {filename} created and edited successfully.")
|
118 |
+
elif cmd.startswith("!"):
|
119 |
+
results.append(execute_command(cmd[1:])) # Remove the leading '!'
|
120 |
+
elif cmd.startswith("show files"):
|
121 |
+
files = os.listdir(current_dir)
|
122 |
+
results.append("Files in current directory:\n" + "\n".join(files))
|
123 |
+
elif cmd.startswith("cd "):
|
124 |
+
new_dir = os.path.join(current_dir, cmd[3:])
|
125 |
+
if os.path.isdir(new_dir):
|
126 |
+
current_dir = os.path.abspath(new_dir)
|
127 |
+
results.append(f"Changed directory to: {current_dir}")
|
128 |
+
else:
|
129 |
+
results.append(f"Error: Directory not found: {new_dir}")
|
130 |
+
else:
|
131 |
+
results.append(execute_command(cmd))
|
132 |
+
|
133 |
+
return jsonify({"result": f"AI Executed:\n{ai_result}\n\nOutput:\n" + "\n".join(results)})
|
134 |
+
elif command == "show files":
|
135 |
+
files = os.listdir(current_dir)
|
136 |
+
return jsonify({"result": "Files in current directory:\n" + "\n".join(files)})
|
137 |
+
elif command == "hide files":
|
138 |
+
return jsonify({"result": "Files hidden."})
|
139 |
+
elif command.startswith("new file "):
|
140 |
+
filename = command[9:].strip()
|
141 |
+
filepath = os.path.join(current_dir, filename)
|
142 |
+
with open(filepath, 'w') as f:
|
143 |
+
pass # Create an empty file
|
144 |
+
return jsonify({"result": f"Created new file: {filename}"})
|
145 |
+
elif command.startswith("edit "):
|
146 |
+
filename = command[5:].strip()
|
147 |
+
filepath = os.path.join(current_dir, filename)
|
148 |
+
if os.path.exists(filepath):
|
149 |
+
return jsonify({"result": "Enter code:", "action": "edit", "filename": filename})
|
150 |
+
else:
|
151 |
+
return jsonify({"result": f"Error: File {filename} not found."})
|
152 |
+
elif command.startswith("cd "):
|
153 |
+
new_dir = os.path.join(current_dir, command[3:])
|
154 |
+
if os.path.isdir(new_dir):
|
155 |
+
current_dir = os.path.abspath(new_dir)
|
156 |
+
return jsonify({"result": f"Changed directory to: {current_dir}"})
|
157 |
+
else:
|
158 |
+
return jsonify({"result": f"Error: Directory not found: {new_dir}"})
|
159 |
elif command.startswith("!"):
|
160 |
result = execute_command(command[1:])
|
161 |
+
elif command.startswith("pip install"):
|
162 |
+
result = execute_command(f"{sys.executable} -m {command}")
|
163 |
+
elif command.startswith("git "):
|
164 |
+
result = execute_command(command)
|
165 |
else:
|
166 |
+
if command.endswith(".py"):
|
167 |
+
result = execute_command(f"{sys.executable} {command}")
|
168 |
+
else:
|
169 |
+
result = execute_command(f"{sys.executable} -c \"{command}\"")
|
170 |
+
return jsonify({"result": result})
|
171 |
except Exception as e:
|
172 |
+
return jsonify({"result": f"Error: {str(e)}"})
|
173 |
+
|
174 |
+
@app.route("/save_file", methods=["POST"])
|
175 |
+
def save_file():
|
176 |
+
filename = request.json.get("filename")
|
177 |
+
content = request.json.get("content")
|
178 |
+
filepath = os.path.join(current_dir, filename)
|
179 |
+
with open(filepath, 'w') as f:
|
180 |
+
f.write(content)
|
181 |
+
return jsonify({"result": f"File {filename} saved successfully."})
|
182 |
+
|
183 |
+
@app.route("/cleanup", methods=["POST"])
|
184 |
+
def cleanup():
|
185 |
+
global temp_dir, current_dir
|
186 |
+
if os.path.exists(temp_dir):
|
187 |
+
shutil.rmtree(temp_dir)
|
188 |
+
temp_dir = tempfile.mkdtemp()
|
189 |
+
current_dir = temp_dir
|
190 |
+
return jsonify({"result": "Temporary files cleaned up."})
|
191 |
+
|
192 |
+
@app.route("/list_files", methods=["GET"])
|
193 |
+
def list_files():
|
194 |
+
files = os.listdir(current_dir)
|
195 |
+
return jsonify({"files": files})
|
196 |
|
197 |
+
@app.route("/download/<path:filename>", methods=["GET"])
|
198 |
def download_file(filename):
|
199 |
return send_from_directory(current_dir, filename, as_attachment=True)
|
200 |
|