Add files via upload
This commit is contained in:
parent
d70528cb6e
commit
ac119effe4
10 changed files with 381 additions and 0 deletions
BIN
chatgpt_code_interface/__pycache__/driver.cpython-39.pyc
Normal file
BIN
chatgpt_code_interface/__pycache__/driver.cpython-39.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
chatgpt_code_interface/__pycache__/exec_term_code.cpython-39.pyc
Normal file
BIN
chatgpt_code_interface/__pycache__/exec_term_code.cpython-39.pyc
Normal file
Binary file not shown.
Binary file not shown.
135
chatgpt_code_interface/driver.py
Normal file
135
chatgpt_code_interface/driver.py
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
from selenium.webdriver.common.keys import Keys
|
||||||
|
|
||||||
|
from undetected_chromedriver import Chrome
|
||||||
|
from selenium.webdriver.chrome.options import Options
|
||||||
|
from selenium.webdriver.common.by import By
|
||||||
|
import bs4
|
||||||
|
import re
|
||||||
|
import time
|
||||||
|
|
||||||
|
from exec_python_code import create_namespace, run_code
|
||||||
|
from exec_term_code import run_shell_command
|
||||||
|
from formating_tools import isolate_code_bloc
|
||||||
|
|
||||||
|
from selenium.webdriver.support.ui import WebDriverWait
|
||||||
|
from selenium.webdriver.support import expected_conditions as EC
|
||||||
|
|
||||||
|
def better_send_keys(element, text):
|
||||||
|
lines = text.split("\n")
|
||||||
|
for i, line in enumerate(lines):
|
||||||
|
element.send_keys(line)
|
||||||
|
if i != len(lines)-1:
|
||||||
|
element.send_keys(Keys.SHIFT + Keys.ENTER)
|
||||||
|
|
||||||
|
class GPTDriver:
|
||||||
|
def __init__(self, headless=False, data_dir="selenium1"):
|
||||||
|
time.sleep(1)
|
||||||
|
chrome_options = Options()
|
||||||
|
|
||||||
|
if headless :
|
||||||
|
chrome_options.add_argument("--headless")
|
||||||
|
|
||||||
|
|
||||||
|
chrome_options.add_argument(f"user-data-dir={data_dir}")
|
||||||
|
|
||||||
|
self.driver = Chrome(options=chrome_options, use_subprocess=True)
|
||||||
|
#full screen
|
||||||
|
self.driver.maximize_window()
|
||||||
|
|
||||||
|
def wait_answer(self):
|
||||||
|
"""Wait until the answer is ready"""
|
||||||
|
xpath = """//*[@id="__next"]/div[2]/div[2]/main/div[2]/form/div/div[1]/button/div"""
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
element = self.driver.find_element(By.XPATH, xpath)
|
||||||
|
#if element contain "stop generating" then continue
|
||||||
|
if "stop generating" in element.text.lower():
|
||||||
|
time.sleep(0.1)
|
||||||
|
continue
|
||||||
|
return element
|
||||||
|
except:
|
||||||
|
time.sleep(0.1)
|
||||||
|
continue
|
||||||
|
|
||||||
|
def create_user_data_dir(self, data_dir="selenium1"):
|
||||||
|
"""Create a user data dir for selenium"""
|
||||||
|
chrome_options = Options()
|
||||||
|
chrome_options.add_argument(f"user-data-dir={data_dir}")
|
||||||
|
chrome_options.add_argument("--disable-images")
|
||||||
|
self.driver = Chrome(options=chrome_options)
|
||||||
|
self.driver.set_window_size(600, 1000)
|
||||||
|
self.driver.get("https://chat.openai.com/chat")
|
||||||
|
time.sleep(60)
|
||||||
|
self.driver.quit()
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
self.driver.get("https://chat.openai.com/chat")
|
||||||
|
|
||||||
|
def get_chat(self):
|
||||||
|
"""Get the chat history"""
|
||||||
|
soup = bs4.BeautifulSoup(self.driver.page_source, "html.parser")
|
||||||
|
chat = soup.find("div", class_=re.compile("flex flex-col items-center text-sm"))
|
||||||
|
return chat
|
||||||
|
|
||||||
|
def get_last_chat(self):
|
||||||
|
"""Get the last chat message"""
|
||||||
|
soup = bs4.BeautifulSoup(self.driver.page_source, "html.parser")
|
||||||
|
#last chat is the last div with class = " group w-full text-gray-800 dark:text-gray-100 border-b border-black/10 dark:border-gray-900/50 bg-gray-50 dark:bg-[#444654]"
|
||||||
|
chat = soup.find_all("div", class_="""group w-full text-gray-800 dark:text-gray-100 border-b border-black/10 dark:border-gray-900/50 bg-gray-50 dark:bg-[#444654]""")[-1]
|
||||||
|
return chat
|
||||||
|
|
||||||
|
def send_message(self, txt):
|
||||||
|
textarea = self.driver.find_element(By.XPATH, '//*[@id="__next"]/div[2]/div[2]/main/div[2]/form/div/div[2]/textarea')
|
||||||
|
better_send_keys(textarea, txt)
|
||||||
|
time.sleep(1)
|
||||||
|
button_send = self.driver.find_element(By.XPATH, '//*[@id="__next"]/div[2]/div[2]/main/div[2]/form/div/div[2]/button')
|
||||||
|
button_send.click()
|
||||||
|
|
||||||
|
def add_run_button(self):
|
||||||
|
#html of a big red button with border-radius of 10%, green background and white text pady by 10px up and padx by 10px left
|
||||||
|
button_html = '<button id="continueButton" style="position: fixed; bottom: 10px; right: 10px; font-size: 2em; background-color: green; color: white; border-radius: 10%;">Continue</button>'
|
||||||
|
xpath = """//*[@id="__next"]/div[2]/div[2]/main/div[2]/div/span"""
|
||||||
|
|
||||||
|
# Find the element using the given XPath
|
||||||
|
element = None
|
||||||
|
while not element:
|
||||||
|
try:
|
||||||
|
element = self.driver.find_element(By.XPATH, xpath)
|
||||||
|
except:
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
# Inject the button after the element found using the XPath
|
||||||
|
self.driver.execute_script(f"arguments[0].insertAdjacentHTML('afterend', '{button_html}');", element)
|
||||||
|
|
||||||
|
# Add the click event listener for the button
|
||||||
|
self.driver.execute_script("""
|
||||||
|
document.getElementById('continueButton').addEventListener('click', function() {
|
||||||
|
window.loopControl1 = 'continue';
|
||||||
|
});
|
||||||
|
""")
|
||||||
|
|
||||||
|
def add_send_result_button(self):
|
||||||
|
#html of a big red button with border-radius of 10%, green background and white text pady by 10px up and padx by 10px left
|
||||||
|
button_html = '<button id="sendResultButton" style="position: fixed; bottom: 10px; right: 10px; font-size: 2em; background-color: green; color: white; border-radius: 10%;">Send result</button>'
|
||||||
|
xpath = """//*[@id="__next"]/div[2]/div[2]/main/div[2]/div/span"""
|
||||||
|
|
||||||
|
# Find the element using the given XPath
|
||||||
|
element = None
|
||||||
|
while not element:
|
||||||
|
try:
|
||||||
|
element = self.driver.find_element(By.XPATH, xpath)
|
||||||
|
except:
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
# Inject the button after the element found using the XPath
|
||||||
|
self.driver.execute_script(f"arguments[0].insertAdjacentHTML('afterend', '{button_html}');", element)
|
||||||
|
|
||||||
|
# Add the click event listener for the button
|
||||||
|
self.driver.execute_script("""
|
||||||
|
document.getElementById('sendResultButton').addEventListener('click', function() {
|
||||||
|
window.loopControl2 = 'send_result';
|
||||||
|
});
|
||||||
|
""")
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self.driver.close()
|
54
chatgpt_code_interface/exec_python_code.py
Normal file
54
chatgpt_code_interface/exec_python_code.py
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import sys
|
||||||
|
import importlib.util
|
||||||
|
import io
|
||||||
|
import contextlib
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
def create_namespace():
|
||||||
|
module_name = "__main__"
|
||||||
|
module_spec = importlib.util.spec_from_loader(module_name, loader=None)
|
||||||
|
module = importlib.util.module_from_spec(module_spec)
|
||||||
|
sys.modules[module_name] = module
|
||||||
|
return module.__dict__
|
||||||
|
|
||||||
|
def run_code(code_str, namespace):
|
||||||
|
# redirect stdout to a buffer to capture output
|
||||||
|
buffer = io.StringIO()
|
||||||
|
with contextlib.redirect_stdout(buffer):
|
||||||
|
try:
|
||||||
|
# compile the code
|
||||||
|
code = compile(code_str, "<string>", "exec")
|
||||||
|
|
||||||
|
# execute the code in the given namespace
|
||||||
|
exec(code, namespace)
|
||||||
|
except Exception as e:
|
||||||
|
# print any errors to the buffer
|
||||||
|
print(f"Error: {e}", file=buffer)
|
||||||
|
traceback.print_exc(file=buffer)
|
||||||
|
|
||||||
|
# return the captured output or error message as a string
|
||||||
|
result = buffer.getvalue().strip()
|
||||||
|
if result:
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
return "---\nProcess finished with no output\n---"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test():
|
||||||
|
code_str1 = '''import numpy as np\nimport matplotlib.pyplot as plt'''
|
||||||
|
code_str2 = '''x = np.linspace(0, 10, 100)\ny = np.sin(x)\nplt.plot(x, y)\nplt.show()'''
|
||||||
|
|
||||||
|
|
||||||
|
namespace = create_namespace()
|
||||||
|
result1 = run_code(code_str1, namespace)
|
||||||
|
result2 = run_code(code_str2, namespace)
|
||||||
|
|
||||||
|
def test2():
|
||||||
|
code_str1 = '''import os'''
|
||||||
|
|
||||||
|
result = run_code(code_str1, create_namespace())
|
||||||
|
print(result)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test()
|
65
chatgpt_code_interface/exec_term_code.py
Normal file
65
chatgpt_code_interface/exec_term_code.py
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import time
|
||||||
|
|
||||||
|
class Shell:
|
||||||
|
def __init__(self):
|
||||||
|
self.cwd = os.getcwd()
|
||||||
|
self.env = os.environ.copy()
|
||||||
|
if os.name == 'nt':
|
||||||
|
self.env['PATH'] += os.pathsep + os.getcwd()
|
||||||
|
|
||||||
|
def run_command(self, command_string, input=None):
|
||||||
|
exit_code, stdout, stderr = 1, 'error', 'error'
|
||||||
|
if input is not None:
|
||||||
|
input = input.encode('utf-8')
|
||||||
|
|
||||||
|
commands = command_string.split('\n')
|
||||||
|
results = []
|
||||||
|
for command in commands:
|
||||||
|
command = command.strip()
|
||||||
|
args = command.split(" ")
|
||||||
|
|
||||||
|
if args[0] == 'cd':
|
||||||
|
if len(args) > 1:
|
||||||
|
path = os.path.join(self.cwd, args[1])
|
||||||
|
if os.path.exists(path) and os.path.isdir(path):
|
||||||
|
self.cwd = os.path.abspath(path)
|
||||||
|
exit_code, stdout, stderr = 0, '', ''
|
||||||
|
else:
|
||||||
|
exit_code, stdout, stderr = 1, '', f"cd: {path}: No such file or directory"
|
||||||
|
|
||||||
|
elif os.name == 'nt':
|
||||||
|
result = subprocess.run(command, cwd=self.cwd, env=self.env, input=input, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, text=False)
|
||||||
|
exit_code, stdout, stderr = result.returncode, result.stdout.decode('utf-8', errors='ignore'), result.stderr.decode('utf-8', errors='ignore')
|
||||||
|
else:
|
||||||
|
result = subprocess.run(args, cwd=self.cwd, env=self.env, input=input, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, text=False)
|
||||||
|
exit_code, stdout, stderr = result.returncode, result.stdout.decode('utf-8',errors='ignore'), result.stderr.decode('utf-8', errors='ignore')
|
||||||
|
|
||||||
|
results.append((command, exit_code, stdout, stderr))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
str_results = ""
|
||||||
|
for result in results:
|
||||||
|
command,exit_code, stdout, stderr = result
|
||||||
|
str_results += f"result for command: {command} :\n exit_code: {exit_code}\n stdout: {stdout}\n stderr: {stderr}\n---------\n"
|
||||||
|
|
||||||
|
return str_results
|
||||||
|
|
||||||
|
shell = Shell()
|
||||||
|
|
||||||
|
def run_shell_command(command_string, input=None):
|
||||||
|
return shell.run_command(command_string, input)
|
||||||
|
|
||||||
|
def test():
|
||||||
|
a = run_shell_command("cd ..\n\ndir")
|
||||||
|
print(type(a))
|
||||||
|
print(a)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
24
chatgpt_code_interface/formating_tools.py
Normal file
24
chatgpt_code_interface/formating_tools.py
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
import bs4
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
|
|
||||||
|
CodeBloc = namedtuple('CodeBloc', ['language', 'code'])
|
||||||
|
|
||||||
|
def remove_trailing_newline(s):
|
||||||
|
if s.endswith('\n'):
|
||||||
|
return s[:-1]
|
||||||
|
return s
|
||||||
|
def isolate_code_bloc(soup):
|
||||||
|
pre_tab = soup.find_all("pre")
|
||||||
|
code_bloc = []
|
||||||
|
for code in pre_tab:
|
||||||
|
#print(code.text)
|
||||||
|
motif = "Copy code"
|
||||||
|
finding = code.text.find(motif)
|
||||||
|
code_content = code.text[finding+len(motif):]
|
||||||
|
language = code.text[:finding]
|
||||||
|
code_bloc.append(CodeBloc(language.strip(), remove_trailing_newline(code_content)))
|
||||||
|
|
||||||
|
print(code_bloc)
|
||||||
|
return code_bloc
|
||||||
|
|
97
chatgpt_code_interface/main.py
Normal file
97
chatgpt_code_interface/main.py
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
from driver import GPTDriver
|
||||||
|
from exec_python_code import create_namespace, run_code
|
||||||
|
from exec_term_code import run_shell_command
|
||||||
|
from formating_tools import isolate_code_bloc
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
gpt_driver = GPTDriver()
|
||||||
|
import time
|
||||||
|
|
||||||
|
def connect_to_gpt_driver():
|
||||||
|
gpt_driver.connect()
|
||||||
|
gpt_driver.add_run_button()
|
||||||
|
time.sleep(3)
|
||||||
|
|
||||||
|
def execute_codes(codes):
|
||||||
|
answer = ""
|
||||||
|
for code in codes:
|
||||||
|
if 'python' in code.language.lower():
|
||||||
|
ans = run_code(code.code, create_namespace())
|
||||||
|
else:
|
||||||
|
ans = run_shell_command(code.code)
|
||||||
|
answer += ans + "\n"
|
||||||
|
return answer
|
||||||
|
|
||||||
|
def wait_continue_button_click():
|
||||||
|
loop_control = gpt_driver.driver.execute_script("return window.loopControl1;")
|
||||||
|
while loop_control != 'continue':
|
||||||
|
time.sleep(0.5)
|
||||||
|
loop_control = gpt_driver.driver.execute_script("return window.loopControl1;")
|
||||||
|
gpt_driver.driver.execute_script("window.loopControl1 = 'stop';")
|
||||||
|
|
||||||
|
def wait_send_results_click():
|
||||||
|
loop_control = gpt_driver.driver.execute_script("return window.loopControl2;")
|
||||||
|
while loop_control != 'send_result':
|
||||||
|
time.sleep(0.5)
|
||||||
|
loop_control = gpt_driver.driver.execute_script("return window.loopControl2;")
|
||||||
|
gpt_driver.driver.execute_script("window.loopControl2 = 'stop';")
|
||||||
|
|
||||||
|
|
||||||
|
def main(launch_first_prompt=False, first_prompt=None):
|
||||||
|
"""Main function"""
|
||||||
|
|
||||||
|
"""
|
||||||
|
-----------------
|
||||||
|
first prompt and execution
|
||||||
|
-----------------
|
||||||
|
"""
|
||||||
|
connect_to_gpt_driver()
|
||||||
|
|
||||||
|
first_prompt = """ I now give you access to a windows computer with python on it.
|
||||||
|
You just have to write code in code blocs and a I will automatically execut it and send you the output.
|
||||||
|
Don't ask the computer to change your code our anything else, it will not understand.
|
||||||
|
So form now on, I will ONLY send you the output of your last python bloc commands you wrote, you can't use os module\n
|
||||||
|
don't ask me anything else, and YOU will ONLY give me some code to execute.
|
||||||
|
Now gather as much information as possible about the limitations of GPT4 and how to overcome them
|
||||||
|
You can only use python to gather online information. bs4 and other usefull libs are already installed YOU DON'T NEED TO INSTALL THINGS\n
|
||||||
|
Sum up the infos in a few lines and get them in a file. Continue gathering information
|
||||||
|
And when you have enough information, write a little article on 'How to get the full potential of GPT4'
|
||||||
|
Your responses should always START with a small reasoning message, then a small todolist with check or X, then the message 'I must gather information online about GPT4 using python, I send code to do that, I HAVE TO ALWAYS VERIFY it worked fine (use print for debugging), then I'll sum up what I learnt in a file \
|
||||||
|
I have to do those things myself without help and I can't ask for any handmade code modification. I can't use an API' """
|
||||||
|
|
||||||
|
"""
|
||||||
|
-----------------
|
||||||
|
main loop
|
||||||
|
-----------------
|
||||||
|
"""
|
||||||
|
|
||||||
|
if launch_first_prompt:
|
||||||
|
answer = first_prompt
|
||||||
|
else:
|
||||||
|
answer = ""
|
||||||
|
|
||||||
|
for j in range(100):
|
||||||
|
print(f"ITERATION {j}")
|
||||||
|
|
||||||
|
|
||||||
|
gpt_driver.send_message(answer)
|
||||||
|
gpt_driver.wait_answer()
|
||||||
|
|
||||||
|
wait_continue_button_click()
|
||||||
|
|
||||||
|
answer = gpt_driver.get_last_chat()
|
||||||
|
codes = isolate_code_bloc(answer)
|
||||||
|
|
||||||
|
answer = execute_codes(codes)
|
||||||
|
|
||||||
|
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
if (j + 5) % 24 == 0:
|
||||||
|
# Wait 3 hours. GPT-4 is limited to 25 requests per 3 hours
|
||||||
|
time.sleep(60 * 60 * 3)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
|
|
6
chatgpt_code_interface/requirements.txt
Normal file
6
chatgpt_code_interface/requirements.txt
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
selenium==4.8.3
|
||||||
|
urllib3==1.26.6
|
||||||
|
matplotlib==3.5.3
|
||||||
|
undetected-chromedriver==3.4.6
|
||||||
|
beautifulsoup4==4.12.0
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue