Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
289 changes: 285 additions & 4 deletions gpt_computer_agent/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,288 @@
from .start import start
try:
from .start import start

from .agentic import Agent
from .agentic import Agent

from .tooler import Tool
from .tooler import Tool
except:
pass
Comment on lines +1 to +8
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve error handling for imports.

The bare except block is too broad and silently ignores all import errors. This could hide important issues.

 try:
     from .start import start
     from .agentic import Agent
     from .tooler import Tool
-except:
+except ImportError as e:
+    import logging
+    logging.warning(f"Failed to import core modules: {e}")
     pass
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try:
from .start import start
from .agentic import Agent
from .agentic import Agent
from .tooler import Tool
from .tooler import Tool
except:
pass
try:
from .start import start
from .agentic import Agent
from .tooler import Tool
except ImportError as e:
import logging
logging.warning(f"Failed to import core modules: {e}")
pass
🧰 Tools
🪛 Ruff (0.8.2)

2-2: .start.start imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


4-4: .agentic.Agent imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


6-6: .tooler.Tool imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


7-7: Do not use bare except

(E722)

__version__ = '0.28.3' # fmt: skip

__version__ = '0.23.0' # fmt: skip




from .classes import BaseClass, BaseVerifier, TypeVerifier, Task

import os
import time
import subprocess
import requests


from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
Comment on lines +23 to +25
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Security concern: SSL certificate verification warnings are globally disabled.

Disabling SSL certificate warnings globally is risky as it could hide potential security issues.

Consider:

  1. Enabling certificate verification and properly handling certificates
  2. If disabling is absolutely necessary, scope it to specific requests
  3. Document the security implications and mitigation strategies




class instance:
def __init__(self, url, tasks=[]):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use a non-mutable default argument.
The current signature def __init__(self, url, tasks=[]) uses a mutable list as a default value. This can cause unintended side effects.

-def __init__(self, url, tasks=[]):
+def __init__(self, url, tasks=None):
     if tasks is None:
         tasks = []

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Ruff (0.8.2)

30-30: Do not use mutable data structures for argument defaults

Replace with None; initialize within function

(B006)

self.url = url
self.task = []
for t in tasks:
self.add_task(t)


def request(self):
pass

def add_task(self, task):
if isinstance(task, list):
for t in task:
self.task.append(t)
else:
self.task.append(task)

for t in self.task:
t.add_client(self)

def kick(self):
for t in self.task:
t.run()

results = []
for t in self.task:
results.append(t.result)

return results


def run(self, task):
task.add_client(self)
task.run()
return task.result


def user_id(self):
from .utils.user_id import load_user_id
return load_user_id()


class interface:
pass



class local_instance(instance):
def __init__(self, *args, **kwargs):
super().__init__("http://localhost:7541", *args, **kwargs)
from .remote import Remote_Client

self.client = Remote_Client(self.url)

def request(self, the_request, the_response, screen=False):

return self.client.request(the_request, the_response, screen)


def start(self):
command = "python -c 'from gpt_computer_agent import start; start(True);'"
self.process = subprocess.Popen(command, shell=True)


def close(self):
try:
self.client.stop_server()
except:
pass

Comment on lines +95 to +99
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve error handling in close() method.

The bare except block silently ignores all errors, which could hide important issues.

     def close(self):
         try:
             self.client.stop_server()
-        except:
+        except Exception as e:
+            import logging
+            logging.debug(f"Failed to stop server gracefully: {e}")
             pass
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try:
self.client.stop_server()
except:
pass
try:
self.client.stop_server()
except Exception as e:
import logging
logging.debug(f"Failed to stop server gracefully: {e}")
pass
🧰 Tools
🪛 Ruff (0.8.2)

95-98: Use contextlib.suppress(Exception) instead of try-except-pass

Replace with contextlib.suppress(Exception)

(SIM105)


97-97: Do not use bare except

(E722)

self.process.terminate()
self.process.wait()



def client_status(self):
return self.client.status




class local(interface):

@staticmethod
def agent( *args, **kwargs):
the_instance = local_instance( *args, **kwargs)
the_instance.start()

time.sleep(5)

client_status = the_instance.client_status()

if not client_status:
raise Exception("Failed to start the local instance")

return the_instance



class cloud_instance(instance):
def __init__(self, *args, **kwargs):
super().__init__("https://free_cloud_1.gca.dev/", *args, **kwargs)


def request(self, the_request, the_response, screen=False):
screen = "false" if not screen else "true"

response = requests.post(self.url+"request", data={"request": the_request, "response": the_response, "screen":screen, "instance":self.instance_id}, verify=False)
json_response = response.json()
request_id = json_response["request_id"]
try:
while True:
response = requests.post(self.url+"request_result", data={"request_id": request_id}, verify=False)
the_json = response.json()
if the_json["status"] == True:
return the_json["result"]
time.sleep(1)
except:
return response.text



def change_profile(self, profile):
response = requests.post(self.url+"change_profile", data={"profile": profile, "instance":self.instance_id}, verify=False)
the_json = response.json()
return the_json["result"]

def add_system_message(self, system_message):
response = requests.post(self.url+"add_system_message", data={"system_message": system_message, "instance":self.instance_id}, verify=False)
the_json = response.json()
return the_json["result"]


def add_user_id(self, user_id):
response = requests.post(self.url+"add_user_id", data={"user_id": user_id, "instance":self.instance_id}, verify=False)
the_json = response.json()
return the_json["result"]

def get_logs(self):
response = requests.post(self.url+"get_logs", data={"instance":self.instance_id}, verify=False)
the_json = response.json()
return the_json["result"]

def reset_memory(self):
response = requests.post(self.url+"reset_memory", data={"instance":self.instance_id}, verify=False)
the_json = response.json()
return the_json["result"]

def screenshot(self):
response = requests.post(self.url+"screenshot_instance", data={"instance":self.instance_id}, verify=False)

its_an_error = False

try:
the_json = response.json()
if "result" in the_json:
its_an_error = True
except:
pass
Comment on lines +183 to +188
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve error handling in screenshot() method.

The bare except block silently ignores JSON parsing errors.

         try:
             the_json = response.json()
             if "result" in the_json:
                 its_an_error = True
-        except:
+        except json.JSONDecodeError:
             pass

Committable suggestion skipped: line range outside the PR's diff.

🧰 Tools
🪛 Ruff (0.8.2)

187-187: Do not use bare except

(E722)



if not its_an_error:
with open('current_screenshot.png', 'wb') as file:
file.write(response.content)
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

img = mpimg.imread('current_screenshot.png')
plt.imshow(img)
plt.axis('off')
plt.show()





def start(self):
req = requests.get(self.url+"start_instance", verify=False)
the_json = req.json()

self.instance_id = the_json["result"]
self.add_user_id(self.user_id())



def close(self):
req = requests.post(self.url+"stop_instance", data={"instance": self.instance_id}, verify=False)
the_json = req.json()
return the_json["result"]

def client_status(self):
return True



class Cloud(interface):

@staticmethod
def agent(*args, **kwargs):
start_time = time.time()

the_instance = cloud_instance( *args, **kwargs)
the_instance.start()
time.sleep(1)

end_time = time.time()

print(f"Time to start the instance: {end_time - start_time}")

return the_instance







class docker_instance(instance):
def __init__(self, url, *args, **kwargs):
super().__init__(url, *args, **kwargs)
from .remote import Remote_Client

self.client = Remote_Client(self.url)

def request(self, the_request, the_response, screen=False):

return self.client.request(the_request, the_response, screen)


def start(self):
pass


def close(self):
pass



def client_status(self):
return self.client.status




class docker(interface):

@staticmethod
def agent(url, *args, **kwargs):
the_instance = docker_instance(url, *args, **kwargs)
the_instance.start()


client_status = the_instance.client_status()

if not client_status:
raise Exception("Failed to start the docker instance")

return the_instance

52 changes: 30 additions & 22 deletions gpt_computer_agent/agent/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,26 @@
from ..llm_settings import llm_settings
from ..tooler import *
from ..display_tools import *
from ..cu.computer import *
from ..teams import *
from .agent_tools import get_tools
from ..mcp.tool import mcp_tools
from ..standard_tools import get_standard_tools

except ImportError:
from llm import get_model
from utils.db import *
from llm_settings import llm_settings
from tooler import *
from display_tools import *
from cu.computer import *
from teams import *
from agent.agent_tools import get_tools
from mcp.tool import mcp_tools
from standard_tools import get_standard_tools


from langgraph.prebuilt import chat_agent_executor
from langgraph.prebuilt import create_react_agent


custom_tools_ = []
Expand Down Expand Up @@ -44,7 +51,7 @@ def get_prompt(name):
return prompt


def get_agent_executor():
def get_agent_executor(the_anthropic_model=False, no_tools=False):
tools = get_tools()
tools += custom_tools()

Expand All @@ -58,23 +65,24 @@ def get_agent_executor():
except ImportError:
pass

if llm_settings[model]["provider"] == "openai":
tools += [
click_on_a_text_on_the_screen,
click_on_a_icon_on_the_screen,
move_on_a_text_on_the_screen,
move_on_a_icon_on_the_screen,
mouse_scroll,
]

tools += [get_texts_on_the_screen]

if (
llm_settings[model]["provider"] == "openai"
or llm_settings[model]["provider"] == "groq"
):
return chat_agent_executor.create_tool_calling_executor(get_model(), tools)

if llm_settings[model]["provider"] == "ollama":
print("Ollama tool len", len(tools))
return chat_agent_executor.create_tool_calling_executor(get_model(), tools)

if the_anthropic_model:
tools += []
if load_aws_access_key_id() == "default":
model_catch = get_model(the_model="claude-3-5-sonnet-20241022")
else:
model_catch = get_model(the_model="us.anthropic.claude-3-5-sonnet-20241022-v2:0")

print("Anthropic model catch", model_catch)
print("Anthropic tools len", len(tools))
return create_react_agent(model_catch, tools)
else:
tools += [mouse_scroll, click_to_text, click_to_icon, click_to_area] + mcp_tools() + get_standard_tools()



if no_tools:
tools = []


return create_react_agent(get_model(), tools)
Loading
Loading