From e8acb0da2a9d3ab60cd725ae18328095dd684efc Mon Sep 17 00:00:00 2001 From: Roshmita-viswa Date: Thu, 9 Oct 2025 12:34:22 +0530 Subject: [PATCH 01/23] first commit --- projects/example-improve/controller.py | 33 +++++++--- projects/example-improve/main.py | 88 ++++++++++++++++++++++++++ projects/example-improve/model.py | 71 ++++++++++++++++++--- projects/example-improve/view.py | 20 +++--- 4 files changed, 185 insertions(+), 27 deletions(-) diff --git a/projects/example-improve/controller.py b/projects/example-improve/controller.py index 6459aed070..dbf42692d8 100644 --- a/projects/example-improve/controller.py +++ b/projects/example-improve/controller.py @@ -1,4 +1,6 @@ +# --- controller.py --- import keyboard +from model import Point # Import Point to define directions class Controller: @@ -7,15 +9,28 @@ def __init__(self, game, view): self.view = view def handle_input(self): - if keyboard.is_pressed("up") and not hasattr(self, "last_key_pressed"): - self.game.move("down") - self.last_key_pressed = "up" - elif hasattr(self, "last_key_pressed") and self.last_key_pressed == "up": - self.game.move("right") - del self.last_key_pressed + # We need a reference to the snake to change its direction + snake = self.game.snake + + # Check for key presses and set the snake's direction using Point objects. + # Note: We must call set_direction on the snake object. + + # UP: Change Y by -1 + if keyboard.is_pressed("up"): + snake.set_direction(Point(0, -1)) + + # DOWN: Change Y by +1 elif keyboard.is_pressed("down"): - self.game.move("up") + snake.set_direction(Point(0, 1)) + + # LEFT: Change X by -1 elif keyboard.is_pressed("left"): - self.game.move("right") + snake.set_direction(Point(-1, 0)) + + # RIGHT: Change X by +1 elif keyboard.is_pressed("right"): - self.game.move("left") + snake.set_direction(Point(1, 0)) + + # Optional: Add an exit key + elif keyboard.is_pressed("esc"): + self.game.is_running = False \ No newline at end of file diff --git a/projects/example-improve/main.py b/projects/example-improve/main.py index 3de503f84e..af24f9e9fe 100644 --- a/projects/example-improve/main.py +++ b/projects/example-improve/main.py @@ -1,9 +1,97 @@ +import sys +import platform +import os +import subprocess +import json +from importlib.metadata import distributions +from rich.console import Console +from rich.table import Table + from controller import Controller from model import Game from view import View +# Sensitive environment variables to mask +SENSITIVE_KEYS = ["OPENAI_API_KEY", "API_KEY", "SECRET", "TOKEN"] + +def get_command_version(command): + """Run a command and return its version, or 'Not found'.""" + try: + result = subprocess.run(command, shell=True, capture_output=True, text=True) + if result.returncode == 0: + return result.stdout.strip().split("\n")[0] + return "Not found" + except Exception: + return "Not found" + +def get_env_variables(): + """Return filtered environment variables with sensitive ones masked.""" + filtered = {} + for key, value in os.environ.items(): + if key in SENSITIVE_KEYS: + filtered[key] = "*****" + elif key in ["PATH", "PYTHONPATH", "VIRTUAL_ENV"]: + filtered[key] = value + return filtered + +def get_installed_packages(): + """Return a dict of installed Python packages and versions.""" + packages = {} + for dist in distributions(): + name = dist.metadata["Name"] + version = dist.version + if name: + packages[name] = version + return packages + +def sysinfo(): + info = { + "gpt_engineer_version": "0.1.0", # Change if your package version differs + "os": platform.system(), + "os_version": platform.version(), + "architecture": platform.machine(), + "python_version": sys.version.split()[0], + "pip_version": get_command_version("pip --version"), + "git_version": get_command_version("git --version"), + "node_version": get_command_version("node --version"), + "env_variables": get_env_variables(), + "installed_packages": get_installed_packages(), + } + + # Pretty print using Rich + console = Console() + console.print("\n[bold cyan]=== System Information ===[/bold cyan]\n") + + table = Table(show_header=True, header_style="bold magenta") + table.add_column("Key", style="cyan", no_wrap=True) + table.add_column("Value", style="green") + + # Top-level info + for key in ["gpt_engineer_version", "os", "os_version", "architecture", "python_version", "pip_version", "git_version", "node_version"]: + table.add_row(key, str(info[key])) + + console.print(table) + + # Environment variables + console.print("\n[bold cyan]Environment Variables:[/bold cyan]") + for k, v in info["env_variables"].items(): + console.print(f"{k}: {v}") + + # Installed packages (optional: print first 30 only) + console.print("\n[bold cyan]Installed Packages (first 30 shown):[/bold cyan]") + for i, (pkg, ver) in enumerate(info["installed_packages"].items()): + if i >= 30: + console.print(f"... ({len(info['installed_packages'])-30} more packages)") + break + console.print(f"{pkg}: {ver}") def main(): + # Check if --sysinfo argument is provided + if "--sysinfo" in sys.argv: + sysinfo() + return + + # Regular game loop game = Game() view = View(game) controller = Controller(game, view) diff --git a/projects/example-improve/model.py b/projects/example-improve/model.py index e5d0b72433..eaf8109ce8 100644 --- a/projects/example-improve/model.py +++ b/projects/example-improve/model.py @@ -1,32 +1,85 @@ +# --- model.py --- import random - from dataclasses import dataclass - +# ------------------------------ +# Data Structures +# ------------------------------ @dataclass class Point: x: int y: int +# ------------------------------ +# Snake Class +# ------------------------------ +class Snake: + def __init__(self, initial_position: Point): + self.body: list[Point] = [initial_position] # Snake starts with one segment + self.direction = Point(1, 0) # Moving right initially + self.grow_next_move = False # Flag to handle growth + + @property + def head(self) -> Point: + """Return the current head of the snake.""" + return self.body[0] + + def set_direction(self, new_direction: Point): + """Change direction if not opposite to current.""" + if (self.direction.x + new_direction.x != 0 or + self.direction.y + new_direction.y != 0): + self.direction = new_direction + def move(self): + """Move the snake in the current direction.""" + new_head = Point( + self.head.x + self.direction.x, + self.head.y + self.direction.y + ) + self.body.insert(0, new_head) # Add new head + if self.grow_next_move: + self.grow_next_move = False # Growth applied, reset flag + else: + self.body.pop() # Remove tail if not growing + + def grow(self): + """Trigger growth on the next move.""" + self.grow_next_move = True + +# ------------------------------ +# Game Class +# ------------------------------ class Game: - def __init__(self): - self.snake = [Point(5, 5)] + def __init__(self, size: int = 10): + self.size = size # Board size (size x size) + self.snake = Snake(initial_position=Point(size // 2, size // 2)) self.food = self.generate_food() self.is_running = True def generate_food(self): - return Point(random.randint(0, 10), random.randint(0, 10)) + """Generate food not overlapping with the snake.""" + while True: + food_point = Point( + random.randint(0, self.size - 1), + random.randint(0, self.size - 1) + ) + if food_point not in self.snake.body: + return food_point def update(self): - # Move the snake + """Update the game state: move snake, handle collisions.""" self.snake.move() - # Check for collision with food + # Check for food collision if self.snake.head == self.food: self.snake.grow() self.food = self.generate_food() - # Check for collision with boundaries - if not (0 <= self.snake.head.x < 10 and 0 <= self.snake.head.y < 10): + # Check for wall collisions + if not (0 <= self.snake.head.x < self.size and + 0 <= self.snake.head.y < self.size): + self.is_running = False + + # Check for self-collision + if self.snake.head in self.snake.body[1:]: self.is_running = False diff --git a/projects/example-improve/view.py b/projects/example-improve/view.py index 78421e5124..62e0592580 100644 --- a/projects/example-improve/view.py +++ b/projects/example-improve/view.py @@ -1,19 +1,21 @@ from model import Point - class View: def __init__(self, game): self.game = game def render(self): - # Print the game state - for y in range(10): - for x in range(10): - if Point(x, y) in self.game.snake: - print("S", end="") - elif Point(x, y) == self.game.food: - print("F", end="") + # Print the game state (10x10 board) + for y in range(self.game.size): + for x in range(self.game.size): + current = Point(x, y) + if current == self.game.snake.head: + print("H", end="") # Head of the snake + elif current in self.game.snake.body[1:]: + print("S", end="") # Body of the snake + elif current == self.game.food: + print("F", end="") # Food else: - print(".", end="") + print(".", end="") # Empty space print() print() From 3a4b005665c02c220c49932708b0e6b83de30973 Mon Sep 17 00:00:00 2001 From: Roshmita-viswa Date: Thu, 9 Oct 2025 14:17:34 +0530 Subject: [PATCH 02/23] FIX: Apply automatic code formatting via pre-commit/black --- projects/example-improve/controller.py | 17 ++++++++-------- projects/example-improve/main.py | 26 +++++++++++++++++++------ projects/example-improve/model.py | 27 ++++++++++++++------------ projects/example-improve/view.py | 1 + 4 files changed, 45 insertions(+), 26 deletions(-) diff --git a/projects/example-improve/controller.py b/projects/example-improve/controller.py index dbf42692d8..60444b23ba 100644 --- a/projects/example-improve/controller.py +++ b/projects/example-improve/controller.py @@ -1,6 +1,7 @@ # --- controller.py --- import keyboard -from model import Point # Import Point to define directions + +from model import Point # Import Point to define directions class Controller: @@ -11,26 +12,26 @@ def __init__(self, game, view): def handle_input(self): # We need a reference to the snake to change its direction snake = self.game.snake - + # Check for key presses and set the snake's direction using Point objects. # Note: We must call set_direction on the snake object. - + # UP: Change Y by -1 if keyboard.is_pressed("up"): snake.set_direction(Point(0, -1)) - + # DOWN: Change Y by +1 elif keyboard.is_pressed("down"): snake.set_direction(Point(0, 1)) - + # LEFT: Change X by -1 elif keyboard.is_pressed("left"): snake.set_direction(Point(-1, 0)) - + # RIGHT: Change X by +1 elif keyboard.is_pressed("right"): snake.set_direction(Point(1, 0)) - + # Optional: Add an exit key elif keyboard.is_pressed("esc"): - self.game.is_running = False \ No newline at end of file + self.game.is_running = False diff --git a/projects/example-improve/main.py b/projects/example-improve/main.py index af24f9e9fe..955c77eb11 100644 --- a/projects/example-improve/main.py +++ b/projects/example-improve/main.py @@ -1,19 +1,20 @@ -import sys -import platform import os +import platform import subprocess -import json +import sys + from importlib.metadata import distributions -from rich.console import Console -from rich.table import Table from controller import Controller from model import Game +from rich.console import Console +from rich.table import Table from view import View # Sensitive environment variables to mask SENSITIVE_KEYS = ["OPENAI_API_KEY", "API_KEY", "SECRET", "TOKEN"] + def get_command_version(command): """Run a command and return its version, or 'Not found'.""" try: @@ -24,6 +25,7 @@ def get_command_version(command): except Exception: return "Not found" + def get_env_variables(): """Return filtered environment variables with sensitive ones masked.""" filtered = {} @@ -34,6 +36,7 @@ def get_env_variables(): filtered[key] = value return filtered + def get_installed_packages(): """Return a dict of installed Python packages and versions.""" packages = {} @@ -44,6 +47,7 @@ def get_installed_packages(): packages[name] = version return packages + def sysinfo(): info = { "gpt_engineer_version": "0.1.0", # Change if your package version differs @@ -67,7 +71,16 @@ def sysinfo(): table.add_column("Value", style="green") # Top-level info - for key in ["gpt_engineer_version", "os", "os_version", "architecture", "python_version", "pip_version", "git_version", "node_version"]: + for key in [ + "gpt_engineer_version", + "os", + "os_version", + "architecture", + "python_version", + "pip_version", + "git_version", + "node_version", + ]: table.add_row(key, str(info[key])) console.print(table) @@ -85,6 +98,7 @@ def sysinfo(): break console.print(f"{pkg}: {ver}") + def main(): # Check if --sysinfo argument is provided if "--sysinfo" in sys.argv: diff --git a/projects/example-improve/model.py b/projects/example-improve/model.py index eaf8109ce8..c0678f62fd 100644 --- a/projects/example-improve/model.py +++ b/projects/example-improve/model.py @@ -1,7 +1,9 @@ # --- model.py --- import random + from dataclasses import dataclass + # ------------------------------ # Data Structures # ------------------------------ @@ -10,6 +12,7 @@ class Point: x: int y: int + # ------------------------------ # Snake Class # ------------------------------ @@ -17,7 +20,7 @@ class Snake: def __init__(self, initial_position: Point): self.body: list[Point] = [initial_position] # Snake starts with one segment self.direction = Point(1, 0) # Moving right initially - self.grow_next_move = False # Flag to handle growth + self.grow_next_move = False # Flag to handle growth @property def head(self) -> Point: @@ -26,16 +29,15 @@ def head(self) -> Point: def set_direction(self, new_direction: Point): """Change direction if not opposite to current.""" - if (self.direction.x + new_direction.x != 0 or - self.direction.y + new_direction.y != 0): + if ( + self.direction.x + new_direction.x != 0 + or self.direction.y + new_direction.y != 0 + ): self.direction = new_direction def move(self): """Move the snake in the current direction.""" - new_head = Point( - self.head.x + self.direction.x, - self.head.y + self.direction.y - ) + new_head = Point(self.head.x + self.direction.x, self.head.y + self.direction.y) self.body.insert(0, new_head) # Add new head if self.grow_next_move: self.grow_next_move = False # Growth applied, reset flag @@ -46,12 +48,13 @@ def grow(self): """Trigger growth on the next move.""" self.grow_next_move = True + # ------------------------------ # Game Class # ------------------------------ class Game: def __init__(self, size: int = 10): - self.size = size # Board size (size x size) + self.size = size # Board size (size x size) self.snake = Snake(initial_position=Point(size // 2, size // 2)) self.food = self.generate_food() self.is_running = True @@ -60,8 +63,7 @@ def generate_food(self): """Generate food not overlapping with the snake.""" while True: food_point = Point( - random.randint(0, self.size - 1), - random.randint(0, self.size - 1) + random.randint(0, self.size - 1), random.randint(0, self.size - 1) ) if food_point not in self.snake.body: return food_point @@ -76,8 +78,9 @@ def update(self): self.food = self.generate_food() # Check for wall collisions - if not (0 <= self.snake.head.x < self.size and - 0 <= self.snake.head.y < self.size): + if not ( + 0 <= self.snake.head.x < self.size and 0 <= self.snake.head.y < self.size + ): self.is_running = False # Check for self-collision diff --git a/projects/example-improve/view.py b/projects/example-improve/view.py index 62e0592580..8a3fd2eee1 100644 --- a/projects/example-improve/view.py +++ b/projects/example-improve/view.py @@ -1,5 +1,6 @@ from model import Point + class View: def __init__(self, game): self.game = game From c5ff4f883c65741d742b796402c101d4d1b14865 Mon Sep 17 00:00:00 2001 From: Roshmita V Date: Thu, 9 Oct 2025 16:03:35 +0530 Subject: [PATCH 03/23] Update pyproject.toml --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index bb229c8c09..d82bc347c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,6 +38,7 @@ pillow = "^10.2.0" datasets = "^2.17.1" black = "23.3.0" langchain-community = "^0.2.0" +packaging = ">=23.1" [tool.poetry.group.dev.dependencies] pytest = ">=7.3.1" From 0e3ec89196b27cea8f5984f711249d84079da0a0 Mon Sep 17 00:00:00 2001 From: Roshmita V Date: Thu, 9 Oct 2025 16:24:20 +0530 Subject: [PATCH 04/23] Update pyproject.toml --- pyproject.toml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index d82bc347c5..5b8fa754b5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ classifiers = [ ] [build-system] -requires = ["poetry-core>=1.0.0"] +requires = ["poetry-core>=1.5.0"] build-backend = "poetry.core.masonry.api" [tool.poetry.dependencies] @@ -39,6 +39,7 @@ datasets = "^2.17.1" black = "23.3.0" langchain-community = "^0.2.0" packaging = ">=23.1" +package-name = " Date: Thu, 9 Oct 2025 16:29:28 +0530 Subject: [PATCH 05/23] Update ci.yaml --- .github/workflows/ci.yaml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 94fae70786..91c9330b1a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -22,10 +22,10 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version == '3.12' && '3.12.3' || matrix.python-version }} # Using 3.12.3 to resolve Pydantic ForwardRef issue cache: 'pip' # Note that pip is for the tox level. Poetry is still used for installing the specific environments (tox.ini) @@ -42,6 +42,14 @@ jobs: env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} run: tox + - name: Install Poetry + run: pip install poetry + + - name: Install dependencies + run: poetry install --no-interaction --no-root + + - name: Run tests + run: poetry run pytest -q # Temporarily disabling codecov until we resolve codecov rate limiting issue # - name: Report coverage From e9aeba8bbfc5e4001f00df832d75f360dfb4fd10 Mon Sep 17 00:00:00 2001 From: Roshmita V Date: Thu, 9 Oct 2025 16:30:32 +0530 Subject: [PATCH 06/23] Update tox.ini --- tox.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tox.ini b/tox.ini index 088b114a25..8da15f851f 100644 --- a/tox.ini +++ b/tox.ini @@ -8,6 +8,8 @@ basepython = py312: python3.12 deps = poetry + pytest commands = poetry install --no-root + poetry run pytest -q poetry run pytest --cov=gpt_engineer --cov-report=xml -k 'not installed_main_execution' From 9a437025514b2566242c735bc261304a4bba8963 Mon Sep 17 00:00:00 2001 From: Roshmita V Date: Thu, 9 Oct 2025 16:32:02 +0530 Subject: [PATCH 07/23] Update ci.yaml --- .github/workflows/ci.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 91c9330b1a..542b2b586a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -50,6 +50,10 @@ jobs: - name: Run tests run: poetry run pytest -q + - name: Install test tools + run: pip install poetry tox + - name: Run tests via tox + run: tox -vv # Temporarily disabling codecov until we resolve codecov rate limiting issue # - name: Report coverage From 162cf70bc90194d185a369305c520b52d9333514 Mon Sep 17 00:00:00 2001 From: Roshmita V Date: Thu, 9 Oct 2025 16:44:11 +0530 Subject: [PATCH 08/23] Update pyproject.toml --- pyproject.toml | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5b8fa754b5..3fdc2b88bb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,7 +28,7 @@ tiktoken = ">=0.0.4" tabulate = "0.9.0" python-dotenv = ">=0.21.0" langchain = ">=0.1.2" -langchain_openai = "*" +langchain_openai = "^0.1.0" toml = ">=0.10.2" tomlkit = "^0.12.4" pyperclip = "^1.8.2" @@ -36,10 +36,9 @@ langchain-anthropic = "^0.1.1" regex = "^2023.12.25" pillow = "^10.2.0" datasets = "^2.17.1" -black = "23.3.0" +black = "^23.3.0" langchain-community = "^0.2.0" -packaging = ">=23.1" -package-name = " Date: Thu, 9 Oct 2025 16:50:33 +0530 Subject: [PATCH 09/23] Update ci.yaml --- .github/workflows/ci.yaml | 81 ++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 542b2b586a..0e771023a7 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,4 +1,4 @@ -name: Tox pytest all python versions +name: ๐Ÿง  Tox + Pytest (All Python Versions) on: push: @@ -16,46 +16,49 @@ concurrency: jobs: test: runs-on: ubuntu-latest + strategy: matrix: python-version: ['3.10', '3.11', '3.12'] steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version == '3.12' && '3.12.3' || matrix.python-version }} # Using 3.12.3 to resolve Pydantic ForwardRef issue - cache: 'pip' # Note that pip is for the tox level. Poetry is still used for installing the specific environments (tox.ini) - - - name: Check Python Version - run: python --version - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install tox==4.15.0 poetry - - - name: Run tox - env: - OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - run: tox - - name: Install Poetry - run: pip install poetry - - - name: Install dependencies - run: poetry install --no-interaction --no-root - - - name: Run tests - run: poetry run pytest -q - - name: Install test tools - run: pip install poetry tox - - name: Run tests via tox - run: tox -vv - - # Temporarily disabling codecov until we resolve codecov rate limiting issue - # - name: Report coverage - # run: | - # bash <(curl -s https://codecov.io/bash) + - name: ๐Ÿ›’ Checkout repository + uses: actions/checkout@v4 + + - name: ๐Ÿ Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + cache: 'pip' + + - name: ๐Ÿงพ Check Python version + run: python --version + + - name: ๐Ÿ“ฆ Upgrade pip and install build tools + run: | + python -m pip install --upgrade pip + pip install poetry tox==4.15.0 + + - name: โš™๏ธ Configure Poetry + run: | + poetry config virtualenvs.create true + poetry config virtualenvs.in-project true + poetry install --no-interaction --no-root + + - name: ๐Ÿงช Run tests with Poetry (pytest) + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + run: | + poetry run pytest -q --maxfail=1 --disable-warnings -v + + - name: ๐Ÿงซ Run tests via Tox (multi-environment) + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + run: | + tox -vv + + # Optional: Enable later when Codecov is stable + # - name: ๐Ÿ“Š Upload coverage + # uses: codecov/codecov-action@v5 + # with: + # fail_ci_if_error: false From e9f9d0f5e8e36717438ab2299aa3dbcf2601446f Mon Sep 17 00:00:00 2001 From: Roshmita V Date: Thu, 9 Oct 2025 16:53:09 +0530 Subject: [PATCH 10/23] Update ci.yaml --- .github/workflows/ci.yaml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 0e771023a7..5fb4b1d66e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,4 +1,4 @@ -name: ๐Ÿง  Tox + Pytest (All Python Versions) +name: Tox + Pytest (All Python Versions) on: push: @@ -22,43 +22,43 @@ jobs: python-version: ['3.10', '3.11', '3.12'] steps: - - name: ๐Ÿ›’ Checkout repository + - name: Checkout repository uses: actions/checkout@v4 - - name: ๐Ÿ Set up Python ${{ matrix.python-version }} + - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} cache: 'pip' - - name: ๐Ÿงพ Check Python version + - name: Check Python version run: python --version - - name: ๐Ÿ“ฆ Upgrade pip and install build tools + - name: Upgrade pip and install build tools run: | python -m pip install --upgrade pip pip install poetry tox==4.15.0 - - name: โš™๏ธ Configure Poetry + - name: Configure Poetry run: | poetry config virtualenvs.create true poetry config virtualenvs.in-project true poetry install --no-interaction --no-root - - name: ๐Ÿงช Run tests with Poetry (pytest) + - name: Run tests with Poetry (pytest) env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} run: | poetry run pytest -q --maxfail=1 --disable-warnings -v - - name: ๐Ÿงซ Run tests via Tox (multi-environment) + - name: Run tests via Tox (multi-environment) env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} run: | tox -vv # Optional: Enable later when Codecov is stable - # - name: ๐Ÿ“Š Upload coverage + # - name: Upload coverage # uses: codecov/codecov-action@v5 # with: # fail_ci_if_error: false From 9f2da6923ab74e306bda603221b2f1f3de3d54c9 Mon Sep 17 00:00:00 2001 From: Roshmita V Date: Thu, 9 Oct 2025 17:05:35 +0530 Subject: [PATCH 11/23] Update pyproject.toml --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 3fdc2b88bb..462466c612 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,6 +39,7 @@ datasets = "^2.17.1" black = "^23.3.0" langchain-community = "^0.2.0" packaging = ">=23.1.0" +pydantic = "<2.0.0" [tool.poetry.group.dev.dependencies] pytest = ">=7.3.1" From 66927c8a11d9dc3c93e3f594a373a1a93ca985ef Mon Sep 17 00:00:00 2001 From: Roshmita V Date: Thu, 9 Oct 2025 17:11:03 +0530 Subject: [PATCH 12/23] Update projects/example-improve/main.py Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> --- projects/example-improve/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/projects/example-improve/main.py b/projects/example-improve/main.py index 955c77eb11..54c4d5f73b 100644 --- a/projects/example-improve/main.py +++ b/projects/example-improve/main.py @@ -50,7 +50,7 @@ def get_installed_packages(): def sysinfo(): info = { - "gpt_engineer_version": "0.1.0", # Change if your package version differs + "gpt_engineer_version": "0.3.1", # Change if your package version differs "os": platform.system(), "os_version": platform.version(), "architecture": platform.machine(), From 0226e9f7c49e667d3eb7654bec3aed9b97fdc65f Mon Sep 17 00:00:00 2001 From: Roshmita V Date: Thu, 9 Oct 2025 17:11:05 +0530 Subject: [PATCH 13/23] Update ci.yaml --- .github/workflows/ci.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5fb4b1d66e..f2f82d38a2 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -51,6 +51,12 @@ jobs: run: | poetry run pytest -q --maxfail=1 --disable-warnings -v + - name: Update lock file + run: poetry lock + - name: Install dependencies + run: poetry install + + - name: Run tests via Tox (multi-environment) env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} From e93924a294367151811650e988924bba37b9e38d Mon Sep 17 00:00:00 2001 From: Roshmita V Date: Thu, 9 Oct 2025 17:13:38 +0530 Subject: [PATCH 14/23] Update ci.yaml --- .github/workflows/ci.yaml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f2f82d38a2..b913eb3e6e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -43,7 +43,12 @@ jobs: run: | poetry config virtualenvs.create true poetry config virtualenvs.in-project true - poetry install --no-interaction --no-root + + # Only lock and install once, right after configuration + - name: Update lock file + run: poetry lock + - name: Install dependencies + run: poetry install --no-interaction --no-root - name: Run tests with Poetry (pytest) env: @@ -51,19 +56,13 @@ jobs: run: | poetry run pytest -q --maxfail=1 --disable-warnings -v - - name: Update lock file - run: poetry lock - - name: Install dependencies - run: poetry install - - - name: Run tests via Tox (multi-environment) env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} run: | tox -vv - # Optional: Enable later when Codecov is stable + # Optional, enable later for codecov # - name: Upload coverage # uses: codecov/codecov-action@v5 # with: From ca3bcda2db77ab9a1c95a6f7d41ed0d0382aa71b Mon Sep 17 00:00:00 2001 From: Roshmita V Date: Thu, 9 Oct 2025 17:20:05 +0530 Subject: [PATCH 15/23] Update ci.yaml --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b913eb3e6e..060cb57f80 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -44,9 +44,9 @@ jobs: poetry config virtualenvs.create true poetry config virtualenvs.in-project true - # Only lock and install once, right after configuration - name: Update lock file run: poetry lock + - name: Install dependencies run: poetry install --no-interaction --no-root From 7ceea41d39acbcbd5e6b40fe2065b6d9ed2511e5 Mon Sep 17 00:00:00 2001 From: Roshmita V Date: Thu, 9 Oct 2025 19:34:06 +0530 Subject: [PATCH 16/23] Update test_install.py --- tests/test_install.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/test_install.py b/tests/test_install.py index 5ee951ceee..7fcdffdbbd 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -6,6 +6,7 @@ import subprocess import sys import venv +import os from pathlib import Path @@ -93,12 +94,18 @@ def test_installed_main_execution(tmp_path, monkeypatch): p = tmp_path / "projects/example" p.mkdir(parents=True) (p / "prompt").write_text("make a program that prints the outcome of 4+4") + + # Pass environment variables including OPENAI_API_KEY explicitly + env = os.environ.copy() + assert 'OPENAI_API_KEY' in env, "OPENAI_API_KEY environment variable is not set" + proc = subprocess.Popen( ["gpte", str(p)], stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True, cwd=tmp_path, + env=env # Pass the environment to the subprocess ) inputs = "Y\nn" From 0abaefdb26fdc159bf3e53138470c131eb7795c7 Mon Sep 17 00:00:00 2001 From: Roshmita V Date: Thu, 9 Oct 2025 19:35:42 +0530 Subject: [PATCH 17/23] Update ci.yaml --- .github/workflows/ci.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 060cb57f80..9bc30ceef9 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -16,6 +16,9 @@ concurrency: jobs: test: runs-on: ubuntu-latest + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + strategy: matrix: From 08b06edd3d60a56b4cfa2edda10c9b89889338f7 Mon Sep 17 00:00:00 2001 From: Roshmita V Date: Thu, 9 Oct 2025 19:42:37 +0530 Subject: [PATCH 18/23] Update test_install.py --- tests/test_install.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/test_install.py b/tests/test_install.py index 7fcdffdbbd..3a9688bb04 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -7,6 +7,7 @@ import sys import venv import os +import subprocess from pathlib import Path @@ -94,18 +95,15 @@ def test_installed_main_execution(tmp_path, monkeypatch): p = tmp_path / "projects/example" p.mkdir(parents=True) (p / "prompt").write_text("make a program that prints the outcome of 4+4") - - # Pass environment variables including OPENAI_API_KEY explicitly env = os.environ.copy() - assert 'OPENAI_API_KEY' in env, "OPENAI_API_KEY environment variable is not set" - + assert 'OPEN_API_KEY' in env, "OPEN_API_KEY environment variable is not set" proc = subprocess.Popen( ["gpte", str(p)], stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True, cwd=tmp_path, - env=env # Pass the environment to the subprocess + env=env ) inputs = "Y\nn" From 05c63d80e1c634e0b0755f1f0c0ddfca435785fd Mon Sep 17 00:00:00 2001 From: Roshmita V Date: Thu, 9 Oct 2025 19:46:43 +0530 Subject: [PATCH 19/23] Update test_install.py --- tests/test_install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_install.py b/tests/test_install.py index 3a9688bb04..2c54e4abbd 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -96,7 +96,7 @@ def test_installed_main_execution(tmp_path, monkeypatch): p.mkdir(parents=True) (p / "prompt").write_text("make a program that prints the outcome of 4+4") env = os.environ.copy() - assert 'OPEN_API_KEY' in env, "OPEN_API_KEY environment variable is not set" + assert 'OPENAI_API_KEY' in env, "OPENAI_API_KEY environment variable is not set" proc = subprocess.Popen( ["gpte", str(p)], stdin=subprocess.PIPE, From d6e87372fe460597e3ed97983d768657855dd47a Mon Sep 17 00:00:00 2001 From: Roshmita V Date: Thu, 9 Oct 2025 19:48:20 +0530 Subject: [PATCH 20/23] Update test_install.py --- tests/test_install.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_install.py b/tests/test_install.py index 2c54e4abbd..091b222682 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -96,14 +96,14 @@ def test_installed_main_execution(tmp_path, monkeypatch): p.mkdir(parents=True) (p / "prompt").write_text("make a program that prints the outcome of 4+4") env = os.environ.copy() - assert 'OPENAI_API_KEY' in env, "OPENAI_API_KEY environment variable is not set" + assert "OPENAI_API_KEY" in env, "OPENAI_API_KEY environment variable is not set" proc = subprocess.Popen( ["gpte", str(p)], stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True, cwd=tmp_path, - env=env + env=env, ) inputs = "Y\nn" From 0231e12fefbb10ab36421e87cf04f292fee960e1 Mon Sep 17 00:00:00 2001 From: Roshmita V Date: Thu, 9 Oct 2025 19:51:10 +0530 Subject: [PATCH 21/23] Update test_install.py --- tests/test_install.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_install.py b/tests/test_install.py index 091b222682..a9db7d1a56 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -2,12 +2,11 @@ Tests for successful installation of the package. """ +import os import shutil import subprocess import sys import venv -import os -import subprocess from pathlib import Path From 825857c0b5204070c06a2088a5a3f0e211d7bd5b Mon Sep 17 00:00:00 2001 From: Roshmita V Date: Thu, 9 Oct 2025 19:56:19 +0530 Subject: [PATCH 22/23] Update ci.yaml --- .github/workflows/ci.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9bc30ceef9..b54ce24c84 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -18,7 +18,6 @@ jobs: runs-on: ubuntu-latest env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} - strategy: matrix: From ec39e91227660a0395082331be8f066f6d16b918 Mon Sep 17 00:00:00 2001 From: Roshmita V Date: Thu, 9 Oct 2025 20:13:03 +0530 Subject: [PATCH 23/23] Update test_install.py --- tests/test_install.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_install.py b/tests/test_install.py index a9db7d1a56..6c2fa41b96 100644 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -48,6 +48,12 @@ def venv_setup_teardown(): finally: # Clean up by removing the virtual environment after tests. shutil.rmtree(VENV_DIR) + try: + subprocess.run(["gpte", "--version"], check=True) + print("gpte is installed") + except (subprocess.CalledProcessError, FileNotFoundError): + print("gpte is NOT installed") + def test_installation():