Skip to content
Open

yes #260

Show file tree
Hide file tree
Changes from all commits
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
3 changes: 3 additions & 0 deletions .vscode/content.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
def example():
content = "Hello"
print(content)
20 changes: 20 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "pwa-msedge",
"name": "Launch Microsoft Edge",
"request": "launch",
"runtimeArgs": [
"--remote-debugging-port=9222"
],
"url": "c:\\Users\\Jim\\.vscode\\extensions\\ms-edgedevtools.vscode-edge-devtools-2.1.9\\out\\startpage\\index.html",
"presentation": {
"hidden": true
}
}
]
}
12 changes: 12 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"DockerRun.DisableDockerrc": true,
"python.testing.unittestArgs": [
"-v",
"-s",
".",
"-p",
"*test.py"
],
"python.testing.pytestEnabled": false,
"python.testing.unittestEnabled": true
}
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
ome


<h1 align="center">Self-Operating Computer Framework</h1>

<p align="center">
Expand Down
185 changes: 185 additions & 0 deletions operate/.pie.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
import os
import sys
try:
from dotenv import load_dotenv
except Exception as e:
raise ImportError("python-dotenv is required: pip install python-dotenv") from e

try:
from ollama import Client
except Exception:
Client = None

try:
from openai import OpenAI
except Exception:
try:
import openai as _openai
OpenAI = getattr(_openai, "OpenAI", None) or _openai
except Exception as e:
raise ImportError("openai package required: pip install openai") from e

try:
import anthropic
except Exception:
anthropic = None

try:
import google.generativeai as genai
except Exception:
genai = None

from prompt_toolkit.shortcuts import input_dialog


class Config:
"""
Configuration class for managing settings.

Attributes:
verbose (bool): Flag indicating whether verbose mode is enabled.
openai_api_key (str): API key for OpenAI.
google_api_key (str): API key for Google.
ollama_host (str): url to ollama running remotely.
"""

_instance = None

def __new__(cls):
if cls._instance is None:
cls._instance = super(Config, cls).__new__(cls)
return cls._instance

def __init__(self):
load_dotenv()
self.verbose = False
self.openai_api_key = None
self.google_api_key = None
self.ollama_host = None
self.anthropic_api_key = None
self.qwen_api_key = None

def initialize_openai(self):
if self.verbose:
print("[Config][initialize_openai]")

api_key = self.openai_api_key or os.getenv("OPENAI_API_KEY")
client = OpenAI(api_key=api_key)
client.api_key = api_key
client.base_url = os.getenv(
"OPENAI_API_BASE_URL", getattr(client, "base_url", None)
)
return client

def initialize_qwen(self):
if self.verbose:
print("[Config][initialize_qwen]")

api_key = self.qwen_api_key or os.getenv("QWEN_API_KEY")
client = OpenAI(
api_key=api_key,
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
client.api_key = api_key
client.base_url = "https://dashscope.aliyuncs.com/compatible-mode/v1"
return client

def initialize_google(self):
if self.verbose:
print("[Config][initialize_google]")

api_key = self.google_api_key or os.getenv("GOOGLE_API_KEY")
genai.configure(api_key=api_key, transport="rest")
model = genai.GenerativeModel("gemini-pro-vision")
return model

def initialize_ollama(self):
if self.ollama_host:
if self.verbose:
print("[Config][initialize_ollama] using cached ollama host")
else:
if self.verbose:
print(
"[Config][initialize_ollama] no cached ollama host. Assuming ollama running locally."
)
self.ollama_host = os.getenv("OLLAMA_HOST", None)
model = Client(host=self.ollama_host)
return model

def initialize_anthropic(self):
api_key = self.anthropic_api_key or os.getenv("ANTHROPIC_API_KEY")
return anthropic.Anthropic(api_key=api_key)

def validation(self, model, voice_mode):
"""
Validate the input parameters for the dialog operation.
"""
self.require_api_key(
"OPENAI_API_KEY",
"OpenAI API key",
model == "gpt-4"
or voice_mode
or model == "gpt-4-with-som"
or model == "gpt-4-with-ocr"
or model == "gpt-4.1-with-ocr"
or model == "o1-with-ocr",
)
self.require_api_key("GOOGLE_API_KEY", "Google API key", model == "gemini-pro-vision")
self.require_api_key("ANTHROPIC_API_KEY", "Anthropic API key", model == "claude-3")
self.require_api_key("QWEN_API_KEY", "Qwen API key", model == "qwen-vl")

def require_api_key(self, key_name, key_description, is_required):
key_exists = bool(os.environ.get(key_name))
if self.verbose:
print("[Config] require_api_key", key_name, key_exists)
if is_required and not key_exists:
self.prompt_and_save_api_key(key_name, key_description)

def prompt_and_save_api_key(self, key_name, key_description):
key_value = input_dialog(
title="API Key Required", text=f"Please enter your {key_description}:"
).run()

if key_value is None: # User pressed cancel or closed the dialog
sys.exit("Operation cancelled by user.")

if key_value:
if key_name == "OPENAI_API_KEY":
self.openai_api_key = key_value
elif key_name == "GOOGLE_API_KEY":
self.google_api_key = key_value
elif key_name == "ANTHROPIC_API_KEY":
self.anthropic_api_key = key_value
elif key_name == "QWEN_API_KEY":
self.qwen_api_key = key_value

self.save_api_key_to_env(key_name, key_value)
load_dotenv() # Reload environment variables

@staticmethod
def save_api_key_to_env(key_name, key_value):
"""
Write or replace a key in the local .env file.
- If .env does not exist, it will be created.
- If the key exists, its value will be replaced.
"""
env_path = ".env"
lines = []
if os.path.exists(env_path):
with open(env_path, "r", encoding="utf-8") as f:
lines = f.readlines()

key_prefix = f"{key_name}="
found = False
new_lines = []
for line in lines:
if line.strip().startswith(f"{key_name}="):
new_lines.append(f"{key_prefix}{key_value}\n")
found = True
else:
new_lines.append(line)
if not found:
new_lines.append(f"{key_prefix}{key_value}\n")

with open(env_path, "w", encoding="utf-8") as f:
f.writelines(new_lines)
Binary file removed readme/key.png
Binary file not shown.
Binary file removed readme/self-operating-computer.png
Binary file not shown.
Binary file removed readme/terminal-access-1.png
Binary file not shown.
Binary file removed readme/terminal-access-2.png
Binary file not shown.