Repository: AntonOsika/gpt-engineer Branch: main Commit: a90fcd543eed Files: 177 Total size: 676.2 KB Directory structure: gitextract_dhh25wks/ ├── .dockerignore ├── .github/ │ ├── CODEOWNERS │ ├── CODE_OF_CONDUCT.md │ ├── CONTRIBUTING.md │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug-report.md │ │ ├── documentation-clarification.md │ │ └── feature-request.md │ ├── PULL_REQUEST_TEMPLATE/ │ │ └── PULL_REQUEST_TEMPLATE.md │ └── workflows/ │ ├── automation.yml │ ├── ci.yaml │ ├── pre-commit.yaml │ └── release.yaml ├── .gitignore ├── .pre-commit-config.yaml ├── .readthedocs.yaml ├── Acknowledgements.md ├── DISCLAIMER.md ├── GOVERNANCE.md ├── LICENSE ├── MANIFEST.in ├── Makefile ├── README.md ├── ROADMAP.md ├── TERMS_OF_USE.md ├── WINDOWS_README.md ├── citation.cff ├── docker/ │ ├── Dockerfile │ ├── README.md │ └── entrypoint.sh ├── docker-compose.yml ├── docs/ │ ├── Makefile │ ├── api_reference.rst │ ├── code_conduct_link.rst │ ├── conf.py │ ├── contributing_link.rst │ ├── create_api_rst.py │ ├── disclaimer_link.rst │ ├── docs_building.md │ ├── examples/ │ │ └── open_llms/ │ │ ├── README.md │ │ ├── langchain_interface.py │ │ └── openai_api_interface.py │ ├── index.rst │ ├── installation.rst │ ├── introduction.md │ ├── make.bat │ ├── open_models.md │ ├── quickstart.rst │ ├── roadmap_link.rst │ ├── terms_link.rst │ ├── tracing_debugging.md │ └── windows_readme_link.rst ├── gpt_engineer/ │ ├── __init__.py │ ├── applications/ │ │ ├── __init__.py │ │ └── cli/ │ │ ├── __init__.py │ │ ├── cli_agent.py │ │ ├── collect.py │ │ ├── file_selector.py │ │ ├── learning.py │ │ └── main.py │ ├── benchmark/ │ │ ├── __init__.py │ │ ├── __main__.py │ │ ├── bench_config.py │ │ ├── benchmarks/ │ │ │ ├── apps/ │ │ │ │ ├── load.py │ │ │ │ ├── problem.py │ │ │ │ └── problems.py │ │ │ ├── gptme/ │ │ │ │ └── load.py │ │ │ ├── load.py │ │ │ └── mbpp/ │ │ │ ├── load.py │ │ │ ├── problem.py │ │ │ └── problems.py │ │ ├── default_bench_config.toml │ │ ├── run.py │ │ └── types.py │ ├── core/ │ │ ├── __init__.py │ │ ├── ai.py │ │ ├── base_agent.py │ │ ├── base_execution_env.py │ │ ├── base_memory.py │ │ ├── chat_to_files.py │ │ ├── default/ │ │ │ ├── __init__.py │ │ │ ├── constants.py │ │ │ ├── disk_execution_env.py │ │ │ ├── disk_memory.py │ │ │ ├── file_store.py │ │ │ ├── paths.py │ │ │ ├── simple_agent.py │ │ │ └── steps.py │ │ ├── diff.py │ │ ├── files_dict.py │ │ ├── git.py │ │ ├── linting.py │ │ ├── preprompts_holder.py │ │ ├── project_config.py │ │ ├── prompt.py │ │ ├── token_usage.py │ │ └── version_manager.py │ ├── preprompts/ │ │ ├── clarify │ │ ├── entrypoint │ │ ├── file_format │ │ ├── file_format_diff │ │ ├── file_format_fix │ │ ├── generate │ │ ├── improve │ │ ├── philosophy │ │ └── roadmap │ └── tools/ │ ├── __init__.py │ ├── custom_steps.py │ └── supported_languages.py ├── projects/ │ ├── example-improve/ │ │ ├── README.md │ │ ├── controller.py │ │ ├── main.py │ │ ├── model.py │ │ ├── prompt │ │ ├── requirements.txt │ │ ├── run.sh │ │ └── view.py │ └── example-vision/ │ ├── navigation.html │ └── prompt ├── pyproject.toml ├── scripts/ │ ├── clean_benchmarks.py │ ├── legacy_benchmark.py │ ├── print_chat.py │ └── test_api.py ├── sweep.yaml ├── tests/ │ ├── __init__.py │ ├── ai_cache.json │ ├── applications/ │ │ ├── __init__.py │ │ └── cli/ │ │ ├── __init__.py │ │ ├── test_cli_agent.py │ │ ├── test_collect.py │ │ ├── test_collection_consent.py │ │ ├── test_learning.py │ │ └── test_main.py │ ├── benchmark/ │ │ └── test_BenchConfig.py │ ├── core/ │ │ ├── __init__.py │ │ ├── default/ │ │ │ ├── __init__.py │ │ │ ├── test_disk_execution_env.py │ │ │ ├── test_disk_file_repository.py │ │ │ ├── test_simple_agent.py │ │ │ └── test_steps.py │ │ ├── improve_function_test_cases/ │ │ │ ├── apps_benchmark_6_chat │ │ │ ├── apps_benchmark_6_code │ │ │ ├── apps_benchmark_6_v2_chat │ │ │ ├── apps_benchmark_6_v2_code │ │ │ ├── controller_chat │ │ │ ├── controller_code │ │ │ ├── corrected_diff_from_missing_lines │ │ │ ├── create_two_new_files_chat │ │ │ ├── create_two_new_files_code │ │ │ ├── simple_calculator_chat │ │ │ ├── simple_calculator_code │ │ │ ├── task_master_chat │ │ │ ├── task_master_code │ │ │ ├── temperature_converter_chat │ │ │ ├── temperature_converter_code │ │ │ ├── theo_case_chat │ │ │ ├── theo_case_code │ │ │ ├── vgvishesh_example_2_chat │ │ │ ├── vgvishesh_example_2_code │ │ │ ├── vgvishesh_example_chat │ │ │ ├── vgvishesh_example_code │ │ │ ├── wheaties_example_chat │ │ │ ├── wheaties_example_code │ │ │ ├── zbf_yml_missing_chat │ │ │ └── zbf_yml_missing_code │ │ ├── test_ai.py │ │ ├── test_chat_to_files.py │ │ ├── test_file_selector_enhancements.py │ │ ├── test_git.py │ │ ├── test_salvage_correct_hunks.py │ │ └── test_token_usage.py │ ├── mock_ai.py │ ├── test_install.py │ ├── test_project_config.py │ └── tools/ │ └── example_snake_files.py └── tox.ini ================================================ FILE CONTENTS ================================================ ================================================ FILE: .dockerignore ================================================ # See https://help.github.com/ignore-files/ for more about ignoring files. # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # Distribution / packaging dist/ build/ *.egg-info/ *.egg # Virtual environments .env .env.sh venv/ ENV/ # IDE-specific files .vscode/ .idea/ # Compiled Python modules *.pyc *.pyo *.pyd # Python testing .pytest_cache/ .ruff_cache/ .coverage .mypy_cache/ # macOS specific files .DS_Store # Windows specific files Thumbs.db # this application's specific files archive # any log file *log.txt todo scratchpad # Ignore GPT Engineer files projects !projects/example # Pyenv .python-version # Benchmark files benchmark !benchmark/*/prompt .gpte_consent ================================================ FILE: .github/CODEOWNERS ================================================ .github/workflows/ @ATheorell ================================================ FILE: .github/CODE_OF_CONDUCT.md ================================================ # Contributor Covenant Code of Conduct ## Our Pledge We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity or expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation. We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. ## Our Standards Examples of behavior that contributes to a positive environment for our community include: * Demonstrating empathy and kindness toward other people * Being respectful of differing opinions, viewpoints, and experiences * Giving and gracefully accepting constructive feedback * Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience * Focusing on what is best not just for us as individuals, but for the overall community Examples of unacceptable behavior include: * The use of sexualized language or imagery, and sexual attention or advances of any kind * Trolling, insulting or derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or email address, without their explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Enforcement Responsibilities Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. ## Scope This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting using an official social media account, or acting as an appointed representative at an online or offline event. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at . All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of reporters of incidents. ## Enforcement Guidelines Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: ### 1. Correction **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. ### 2. Warning **Community Impact**: A violation through a single incident or series of actions. **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. ### 3. Temporary Ban **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. ### 4. Permanent Ban **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. **Consequence**: A permanent ban from any sort of public interaction within the community. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, available at [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at [https://www.contributor-covenant.org/translations][translations]. [homepage]: https://www.contributor-covenant.org [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html [Mozilla CoC]: https://github.com/mozilla/diversity [FAQ]: https://www.contributor-covenant.org/faq [translations]: https://www.contributor-covenant.org/translations ================================================ FILE: .github/CONTRIBUTING.md ================================================ # Contributing to gpt-engineer The gpt-engineer is a community project and lives from your contributions - they are warmly appreciated. The main contribution avenues are: - Pull request: implement code and have it reviewed and potentially merged by the maintainers. Implementations of existing feature requests or fixes to bug reports are likely to be merged. - Bug report: report when something in gpt-engineer doesn't work. Do not report errors in programs written _by_ gpt-engineer. - Feature request: provide a detailed sketch about something you want to have implemented in gpt-engineer. There is no guarantee that features will be implemented. - Discussion: raise awareness of a potential improvement. This is often a good starting point before making a detailed feature request. By participating in this project, you agree to abide by the [code of conduct](https://github.com/gpt-engineer-org/gpt-engineer/blob/main/.github/CODE_OF_CONDUCT.md). ## Merge Policy for Pull Requests Code that is likely to introduce breaking changes, or significantly change the user experience for users and developers, require [board approval](https://github.com/gpt-engineer-org/gpt-engineer/blob/main/GOVERNANCE.md) to be merged. Smaller code changes can be merged directly. As a rule, cosmetic pull requests, for example rephrasing the readme or introducing more compact syntax, that do not yield clear practical improvements are not merged. Such pull requests are generally discouraged, both to save time for the maintainers and to establish a lower bar for becoming a contributor. ## Getting Started with Pull Requests to gpt-engineer To get started with contributing, please follow these steps: 1. Fork the repository and clone it to your local machine. 2. Install any necessary dependencies. 3. Create a new branch for your changes: `git checkout -b my-branch-name`. 4. Make your desired changes or additions. 5. Run the tests to ensure everything is working as expected. 6. Commit your changes: `git commit -m "Descriptive commit message"`. 7. Push to the branch: `git push origin my-branch-name`. 8. Submit a pull request to the `main` branch of the original repository. ## Code Style Please make sure to follow the established code style guidelines for this project. Consistent code style helps maintain readability and makes it easier for others to contribute to the project. To enforce this we use [`pre-commit`](https://pre-commit.com/) to run [`black`](https://black.readthedocs.io/en/stable/index.html) and [`ruff`](https://beta.ruff.rs/docs/) on every commit. To install gpt-engineer as a developer, clone the repository and install the dependencies with: ```bash $ poetry install $ poetry shell ``` And then install the `pre-commit` hooks with: ```bash $ pre-commit install # output: pre-commit installed at .git/hooks/pre-commit ``` If you are not familiar with the concept of [git hooks](https://git-scm.com/docs/githooks) and/or [`pre-commit`](https://pre-commit.com/) please read the documentation to understand how they work. As an introduction of the actual workflow, here is an example of the process you will encounter when you make a commit: Let's add a file we have modified with some errors, see how the pre-commit hooks run `black` and fails. `black` is set to automatically fix the issues it finds: ```bash $ git add chat_to_files.py $ git commit -m "commit message" black....................................................................Failed - hook id: black - files were modified by this hook reformatted chat_to_files.py All done! ✨ 🍰 ✨ 1 file reformatted. ``` You can see that `chat_to_files.py` is both staged and not staged for commit. This is because `black` has formatted it and now it is different from the version you have in your working directory. To fix this you can simply run `git add chat_to_files.py` again and now you can commit your changes. ```bash $ git status On branch pre-commit-setup Changes to be committed: (use "git restore --staged ..." to unstage) modified: chat_to_files.py Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git restore ..." to discard changes in working directory) modified: chat_to_files.py ``` Now let's add the file again to include the latest commits and see how `ruff` fails. ```bash $ git add chat_to_files.py $ git commit -m "commit message" black....................................................................Passed ruff.....................................................................Failed - hook id: ruff - exit code: 1 - files were modified by this hook Found 2 errors (2 fixed, 0 remaining). ``` Same as before, you can see that `chat_to_files.py` is both staged and not staged for commit. This is because `ruff` has formatted it and now it is different from the version you have in your working directory. To fix this you can simply run `git add chat_to_files.py` again and now you can commit your changes. ```bash $ git add chat_to_files.py $ git commit -m "commit message" black....................................................................Passed ruff.....................................................................Passed fix end of files.........................................................Passed [pre-commit-setup f00c0ce] testing 1 file changed, 1 insertion(+), 1 deletion(-) ``` Now your file has been committed and you can push your changes. At the beginning this might seem like a tedious process (having to add the file again after `black` and `ruff` have modified it) but it is actually very useful. It allows you to see what changes `black` and `ruff` have made to your files and make sure that they are correct before you commit them. ### Important Note When `pre-commit` Fails in the Build Pipeline Sometimes `pre-commit` will seemingly run successfully, as follows: ```bash black................................................(no files to check)Skipped ruff.................................................(no files to check)Skipped check toml...........................................(no files to check)Skipped check yaml...........................................(no files to check)Skipped detect private key...................................(no files to check)Skipped fix end of files.....................................(no files to check)Skipped trim trailing whitespace.............................(no files to check)Skipped ``` However, you may see `pre-commit` fail in the build pipeline upon submitting a PR. The solution to this is to run `pre-commit run --all-files` to force `pre-commit` to execute these checks, and make any necessary file modifications, to all files. ## Licensing By contributing to gpt-engineer, you agree that your contributions will be licensed under the [LICENSE](https://github.com/gpt-engineer-org/gpt-engineer/blob/main/LICENSE) file of the project. Thank you for your interest in contributing to gpt-engineer! We appreciate your support and look forward to your contributions. ================================================ FILE: .github/FUNDING.yml ================================================ # These are supported funding model platforms github: [antonosika] patreon: gpt_eng ================================================ FILE: .github/ISSUE_TEMPLATE/bug-report.md ================================================ --- name: Bug report about: Create a report to help us improve title: '' labels: bug, triage assignees: '' --- ## Policy and info - Maintainers will close issues that have been stale for 14 days if they contain relevant answers. - Adding the label "sweep" will automatically turn the issue into a coded pull request. Works best for mechanical tasks. More info/syntax at: https://docs.sweep.dev/ ## Expected Behavior Please describe the behavior you are expecting. ## Current Behavior What is the current behavior? ## Failure Information Information about the failure, including environment details, such as LLM used. ### Failure Logs If your project includes a debug_log_file.txt, kindly upload it from your_project/.gpteng/memory/ directory. This file encompasses all the necessary logs. Should the file prove extensive, consider utilizing GitHub's "add files" functionality. ## System Information Please copy and paste the output of the `gpte --sysinfo` command as part of your bug report. ## Installation Method Please specify whether you installed GPT-Engineer using `pip install` or by building the repository. ================================================ FILE: .github/ISSUE_TEMPLATE/documentation-clarification.md ================================================ --- name: Documentation improvement about: Inaccuracies, inadequacies in the docs pages title: '' labels: documentation, triage assignees: '' --- ## Policy and info - Maintainers will close issues that have been stale for 14 days if they contain relevant answers. - Adding the label "sweep" will automatically turn the issue into a coded pull request. Works best for mechanical tasks. More info/syntax at: https://docs.sweep.dev/ ## Description A clear and concise description of how the documentation at https://gpt-engineer.readthedocs.io/en/latest/ is providing wrong/insufficient information. ## Suggestion How can it be improved ================================================ FILE: .github/ISSUE_TEMPLATE/feature-request.md ================================================ --- name: Feature request about: Suggest an idea for this project title: '' labels: enhancement, triage assignees: '' --- ## Policy and info - Maintainers will close issues that have been stale for 14 days if they contain relevant answers. - Adding the label "sweep" will automatically turn the issue into a coded pull request. Works best for mechanical tasks. More info/syntax at: https://docs.sweep.dev/ - Consider adding the label "good first issue" for interesting, but easy features. ## Feature description A clear and concise description of what you would like to have ## Motivation/Application Why is this feature useful? ================================================ FILE: .github/PULL_REQUEST_TEMPLATE/PULL_REQUEST_TEMPLATE.md ================================================ **YOU MAY DELETE THE ENTIRE TEMPLATE BELOW.** ## How Has This Been Tested? Please describe if you have either: - Generated the "example" project - Ran the entire benchmark suite - Something else ================================================ FILE: .github/workflows/automation.yml ================================================ name: Automation Workflow on: schedule: - cron: '0 0 * * *' issues: types: [opened, edited, reopened] pull_request: types: [opened, edited, reopened] jobs: mark-stale-issues: runs-on: ubuntu-latest steps: - name: Mark stale issues uses: actions/stale@v4 with: stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.' days-before-stale: 60 # Add additional jobs as needed # job-name: # runs-on: ubuntu-latest # steps: # - name: Job step name # uses: action-name@version # with: # parameter1: value1 # ================================================ FILE: .github/workflows/ci.yaml ================================================ name: Tox pytest all python versions on: push: branches: [ main ] paths: - gpt_engineer/** - tests/** pull_request: branches: [ main ] concurrency: group: ${{ github.workflow }} - ${{ github.ref }} cancel-in-progress: true jobs: test: runs-on: ubuntu-latest strategy: matrix: python-version: ['3.10', '3.11', '3.12'] steps: - name: Checkout repository uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 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 # Temporarily disabling codecov until we resolve codecov rate limiting issue # - name: Report coverage # run: | # bash <(curl -s https://codecov.io/bash) ================================================ FILE: .github/workflows/pre-commit.yaml ================================================ name: pre-commit on: pull_request: push: branches: [main] jobs: pre-commit: runs-on: ubuntu-latest permissions: contents: write steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 - uses: pre-commit/action@v3.0.0 with: extra_args: --all-files ================================================ FILE: .github/workflows/release.yaml ================================================ name: Build and publish Python packages to PyPI on: workflow_dispatch: release: types: - published jobs: build: runs-on: ubuntu-latest strategy: matrix: python-version: - "3.10" steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} # Removed the cache line that was here # Install Poetry - name: Install Poetry run: | curl -sSL https://install.python-poetry.org | python3 - # Add Poetry to PATH - name: Add Poetry to PATH run: echo "$HOME/.local/bin" >> $GITHUB_PATH # Cache Poetry's dependencies based on the lock file - name: Set up Poetry cache uses: actions/cache@v3 with: path: ~/.cache/pypoetry key: ${{ runner.os }}-poetry-${{ hashFiles('**/poetry.lock') }} restore-keys: | ${{ runner.os }}-poetry- # Install dependencies using Poetry (if any) - name: Install dependencies run: poetry install # Build package using Poetry - name: Build package run: poetry build --format sdist # Upload package as build artifact - uses: actions/upload-artifact@v3 with: name: package path: dist/ publish: runs-on: ubuntu-latest needs: build environment: name: pypi url: https://pypi.org/p/gpt-engineer permissions: id-token: write steps: - uses: actions/download-artifact@v3 with: name: package path: dist/ - name: Publish packages to PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: password: ${{ secrets.PYPI_API_TOKEN }} ================================================ FILE: .gitignore ================================================ # See https://help.github.com/ignore-files/ for more about ignoring files. # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class .history/ # Distribution / packaging dist/ build/ *.egg-info/ *.egg # Virtual environments .env .env.sh venv/ ENV/ venv_test_installation/ # IDE-specific files .vscode/ .idea/ # Compiled Python modules *.pyc *.pyo *.pyd # Python testing .pytest_cache/ .ruff_cache/ .mypy_cache/ .coverage coverage.* # macOS specific files .DS_Store # Windows specific files Thumbs.db # this application's specific files archive # any log file *log.txt todo scratchpad # Pyenv .python-version .gpte_consent # projects folder apart from default prompt projects/* !projects/example/prompt !projects/example-improve !projects/example-vision # docs docs/_build docs/applications docs/benchmark docs/cli docs/core docs/intro docs/tools # coding assistants .aider* .gpteng # webapp specific webapp/node_modules webapp/package-lock.json webapp/.next/ .langchain.db # TODO files /!todo* #ignore tox files .tox # locally saved datasets gpt_engineer/benchmark/benchmarks/apps/dataset gpt_engineer/benchmark/benchmarks/mbpp/dataset gpt_engineer/benchmark/minimal_bench_config.toml test.json ================================================ FILE: .pre-commit-config.yaml ================================================ # See https://pre-commit.com for more information # See https://pre-commit.com/hooks.html for more hooks fail_fast: true default_stages: [commit] repos: - repo: https://github.com/psf/black rev: 23.3.0 hooks: - id: black args: [--config, pyproject.toml] types: [python] - repo: https://github.com/charliermarsh/ruff-pre-commit rev: "v0.0.272" hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 hooks: - id: check-toml - id: check-yaml - id: detect-private-key - id: end-of-file-fixer - id: trailing-whitespace ================================================ FILE: .readthedocs.yaml ================================================ # .readthedocs.yaml # Read the Docs configuration file # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details # Required version: 2 # Set the OS, Python version and other tools you might need build: os: ubuntu-22.04 tools: python: "3.11" # You can also specify other tool versions: # nodejs: "19" # rust: "1.64" # golang: "1.19" jobs: post_create_environment: - pip install poetry post_install: - VIRTUAL_ENV=$READTHEDOCS_VIRTUALENV_PATH poetry install --with docs pre_build: - python docs/create_api_rst.py # Build documentation in the "docs/" directory with Sphinx sphinx: configuration: docs/conf.py # Optionally build your docs in additional formats such as PDF and ePub # formats: # - pdf # - epub # Optional but recommended, declare the Python requirements required # to build your documentation # See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html #python: # install: # - requirements: docs/requirements.txt ================================================ FILE: Acknowledgements.md ================================================ # We thank the following people for inspiration | Person | Content | File(s) | Source | |----|---|---|---| | Paul Gauthier | The prompt for the `improve code` step is strongly based on Paul's prompt in Aider | /preprompts/improve.txt | https://github.com/paul-gauthier/aider/blob/main/aider/coders/editblock_coder.py ================================================ FILE: DISCLAIMER.md ================================================ # Disclaimer gpt-engineer is an experimental application and is provided "as-is" without any warranty, express or implied. By using this software, you agree to assume all risks associated with its use, including but not limited to data loss, system failure, or any other issues that may arise. The developers and contributors of this project do not accept any responsibility or liability for any losses, damages, or other consequences that may occur as a result of using this software. You are solely responsible for any decisions and actions taken based on the information provided by gpt-engineer. Please note that the use of the GPT-4 language model can be expensive due to its token usage. By utilizing this project, you acknowledge that you are responsible for monitoring and managing your own token usage and the associated costs. It is highly recommended to check your OpenAI API usage regularly and set up any necessary limits or alerts to prevent unexpected charges. As an autonomous experiment, gpt-engineer may generate code or take actions that are not in line with real-world business practices or legal requirements. It is your responsibility to ensure that any actions or decisions made by the generated code comply with all applicable laws, regulations, and ethical standards. The developers and contributors of this project shall not be held responsible for any consequences arising from the use of this software. By using gpt-engineer, you agree to indemnify, defend, and hold harmless the developers, contributors, and any affiliated parties from and against any and all claims, damages, losses, liabilities, costs, and expenses (including reasonable attorneys' fees) arising from your use of this software or your violation of these terms. ================================================ FILE: GOVERNANCE.md ================================================ # Governance Model of GPT-Engineer ## I. Project Board Structure ### Project Board The Project Board is the central decision-making body for the project, overseeing both strategic and technical decisions of the open source project GPT-Engineer. #### Composition: - The Board consists of the project's founder, Anton Osika, and representatives from each significant contributing entity, including individual contributors and commercial partners. - The board is restricted to a maximum of 7 seats. - New board members are admitted by majority vote. - Board members may be expelled by majority vote. ## II. Roles and Responsibilities ### Veto due to Ethical Considerations - The founder has veto right over any decisions made by the Board. - This veto power is a safeguard to ensure the project's direction remains true to its original vision and ethos. ### Contribution-Conditioned Decision Making - Each board member has one vote as long as they qualify as active contributors. - To qualify as an active contributor, a board member or the entity they represent, must have made 6 significant contributions on the GPT-Engineer GitHub page over the past 90 days. - A significant contribution is: - A merged pull request with at least 3 lines of code. - Engagement in a GitHub/Discord bug report, where the board members' input leads to the confirmed resolution of the bug. If the solution is in terms of a merged pull request, the bug resolution together with the merged pull request counts as one significant contribution. - A non-code, but necessary, community activity agreed on by the board, such as administration, corporate design, workflow design etc, deemed to take more than 1 hour. Participation in meetings or discussions does not count as a significant contribution. - A board member may retain its seat on the board without voting right. ## III. Decision-Making Process ### Majority Voting - Decisions are made based on a simple majority vote. Majority means more than half of board members with voting rights agree on one decision, regardless of the number of choices. - The founder's veto can override the majority decision if exercised. ### Regular Meetings and Reporting - The Board will convene regularly, with the frequency of meetings decided by the Board members. - Decisions, discussion points, and contributions will be transparently documented and shared within the project community. ## IV. Data Access and Confidentiality ### Board Members' Right to Access Data - Any confidential data collected by GPT-Engineer is accessible to the board members after signing a relevant non-disclosure agreement (NDA). - A relevant NDA requires a board member to erase any copies of confidential data obtained by the time of leaving the board. ## V. Scope of Voting ### Essential Topics - Board voting is restricted to essential topics. - Essential topics include essential technical topics and essential community topics. - An essential technical topic is a change in the GPT-engineer code base that is likely to introduce breaking changes, or significantly change the user experience for users and developers. - Essential community topics are changes to the community's governance or other central policy documents such as the readme or license. - Day-to-day tasks such as bug fixes or implementation of new features outside the core module do not require voting. ## VI. Transparency ### Commitment to Transparency - The governance process will be transparent, with key decisions, meeting minutes, and voting results publicly available, except for sensitive or confidential matters. ## VII. Amendments ### Changes to Governance Structure - The governance model can be revised as the project evolves. Proposals for changes can be made by any Board member and will require a majority vote for adoption. ## VIII. The GPT-Engineer Brand ### Copyright and Stewardship - The creator of GPT-engineer (Anton Osika) will be the steward of the GPT-engineer brand to decide when and how it can be used, and is committed to never jeopardizing the interest of the open source community in this stewardship. - Anton Osika possesses the exclusive intellectual property rights for the trademark 'GPT-engineer,' encompassing all case variations such as 'gpt-engineer,' 'GPT-engineer,' and 'GPTE.' This ownership extends to the exclusive legal authority to utilize the 'GPT-engineer' trademark in the establishment and branding of both commercial and non-profit entities. It includes, but is not limited to, the use of the trademark in business names, logos, marketing materials, and other forms of corporate identity. Any use of the 'GPT-engineer' trademark, in any of its case variations, by other parties for commercial or non-commercial purposes requires express permission or a license agreement from Anton Osika. # Current Board Members - Anton Osika - Axel Theorell - Corey Gallon - Peter Harrington - Theo McCabe ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2023 Anton Osika Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: MANIFEST.in ================================================ recursive-include gpt_engineer/preprompts * ================================================ FILE: Makefile ================================================ #Sets the default shell for executing commands as /bin/bash and specifies command should be executed in a Bash shell. SHELL := /bin/bash # Color codes for terminal output COLOR_RESET=\033[0m COLOR_CYAN=\033[1;36m COLOR_GREEN=\033[1;32m # Defines the targets help, install, dev-install, and run as phony targets. .PHONY: help install run #sets the default goal to help when no target is specified on the command line. .DEFAULT_GOAL := help #Disables echoing of commands. .SILENT: #Sets the variable name to the second word from the MAKECMDGOALS. name := $(word 2,$(MAKECMDGOALS)) #Defines a target named help. help: @echo "Please use 'make ' where is one of the following:" @echo " help Return this message with usage instructions." @echo " install Will install the dependencies using Poetry." @echo " run Runs GPT Engineer on the folder with the given name." #Defines a target named install. This target will install the project using Poetry. install: poetry-install install-pre-commit farewell #Defines a target named poetry-install. This target will install the project dependencies using Poetry. poetry-install: @echo -e "$(COLOR_CYAN)Installing project with Poetry...$(COLOR_RESET)" && \ poetry install #Defines a target named install-pre-commit. This target will install the pre-commit hooks. install-pre-commit: @echo -e "$(COLOR_CYAN)Installing pre-commit hooks...$(COLOR_RESET)" && \ poetry run pre-commit install #Defines a target named farewell. This target will print a farewell message. farewell: @echo -e "$(COLOR_GREEN)All done!$(COLOR_RESET)" #Defines a target named run. This target will run GPT Engineer on the folder with the given name. run: @echo -e "$(COLOR_CYAN)Running GPT Engineer on $(COLOR_GREEN)$(name)$(COLOR_CYAN) folder...$(COLOR_RESET)" && \ poetry run gpt-engineer projects/$(name) # Counts the lines of code in the project cloc: cloc . --exclude-dir=node_modules,dist,build,.mypy_cache,benchmark --exclude-list-file=.gitignore --fullpath --not-match-d='docs/_build' --by-file ================================================ FILE: README.md ================================================ # gpt-engineer [![GitHub Repo stars](https://img.shields.io/github/stars/gpt-engineer-org/gpt-engineer?style=social)](https://github.com/gpt-engineer-org/gpt-engineer) [![Discord Follow](https://dcbadge.vercel.app/api/server/8tcDQ89Ej2?style=flat)](https://discord.gg/8tcDQ89Ej2) [![License](https://img.shields.io/github/license/gpt-engineer-org/gpt-engineer)](https://github.com/gpt-engineer-org/gpt-engineer/blob/main/LICENSE) [![GitHub Issues or Pull Requests](https://img.shields.io/github/issues/gpt-engineer-org/gpt-engineer)](https://github.com/gpt-engineer-org/gpt-engineer/issues) ![GitHub Release](https://img.shields.io/github/v/release/gpt-engineer-org/gpt-engineer) [![Twitter Follow](https://img.shields.io/twitter/follow/antonosika?style=social)](https://twitter.com/antonosika) The OG code genereation experimentation platform! If you are looking for the evolution that is an opinionated, managed service – check out gptengineer.app. If you are looking for a well maintained hackable CLI for – check out aider. gpt-engineer lets you: - Specify software in natural language - Sit back and watch as an AI writes and executes the code - Ask the AI to implement improvements ## Getting Started ### Install gpt-engineer For **stable** release: - `python -m pip install gpt-engineer` For **development**: - `git clone https://github.com/gpt-engineer-org/gpt-engineer.git` - `cd gpt-engineer` - `poetry install` - `poetry shell` to activate the virtual environment We actively support Python 3.10 - 3.12. The last version to support Python 3.8 - 3.9 was [0.2.6](https://pypi.org/project/gpt-engineer/0.2.6/). ### Setup API key Choose **one** of: - Export env variable (you can add this to .bashrc so that you don't have to do it each time you start the terminal) - `export OPENAI_API_KEY=[your api key]` - .env file: - Create a copy of `.env.template` named `.env` - Add your OPENAI_API_KEY in .env - Custom model: - See [docs](https://gpt-engineer.readthedocs.io/en/latest/open_models.html), supports local model, azure, etc. Check the [Windows README](./WINDOWS_README.md) for Windows usage. **Other ways to run:** - Use Docker ([instructions](docker/README.md)) - Do everything in your browser: [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://github.com/gpt-engineer-org/gpt-engineer/codespaces) ### Create new code (default usage) - Create an empty folder for your project anywhere on your computer - Create a file called `prompt` (no extension) inside your new folder and fill it with instructions - Run `gpte ` with a relative path to your folder - For example: `gpte projects/my-new-project` from the gpt-engineer directory root with your new folder in `projects/` ### Improve existing code - Locate a folder with code which you want to improve anywhere on your computer - Create a file called `prompt` (no extension) inside your new folder and fill it with instructions for how you want to improve the code - Run `gpte -i` with a relative path to your folder - For example: `gpte projects/my-old-project -i` from the gpt-engineer directory root with your folder in `projects/` ### Benchmark custom agents - gpt-engineer installs the binary 'bench', which gives you a simple interface for benchmarking your own agent implementations against popular public datasets. - The easiest way to get started with benchmarking is by checking out the [template](https://github.com/gpt-engineer-org/gpte-bench-template) repo, which contains detailed instructions and an agent template. - Currently supported benchmark: - [APPS](https://github.com/hendrycks/apps) - [MBPP](https://github.com/google-research/google-research/tree/master/mbpp) The community has started work with different benchmarking initiatives, as described in [this Loom](https://www.loom.com/share/206805143fbb4302b5455a5329eaab17?sid=f689608f-8e49-44f7-b55f-4c81e9dc93e6) video. ### Research Some of our community members have worked on different research briefs that could be taken further. See [this document](https://docs.google.com/document/d/1qmOj2DvdPc6syIAm8iISZFpfik26BYw7ZziD5c-9G0E/edit?usp=sharing) if you are interested. ## Terms By running gpt-engineer, you agree to our [terms](https://github.com/gpt-engineer-org/gpt-engineer/blob/main/TERMS_OF_USE.md). ## Relation to gptengineer.app (GPT Engineer) [gptengineer.app](https://gptengineer.app/) is a commercial project for the automatic generation of web apps. It features a UI for non-technical users connected to a git-controlled codebase. The gptengineer.app team is actively supporting the open source community. ## Features ### Pre Prompts You can specify the "identity" of the AI agent by overriding the `preprompts` folder with your own version of the `preprompts`. You can do so via the `--use-custom-preprompts` argument. Editing the `preprompts` is how you make the agent remember things between projects. ### Vision By default, gpt-engineer expects text input via a `prompt` file. It can also accept image inputs for vision-capable models. This can be useful for adding UX or architecture diagrams as additional context for GPT Engineer. You can do this by specifying an image directory with the `—-image_directory` flag and setting a vision-capable model in the second CLI argument. E.g. `gpte projects/example-vision gpt-4-vision-preview --prompt_file prompt/text --image_directory prompt/images -i` ### Open source, local and alternative models By default, gpt-engineer supports OpenAI Models via the OpenAI API or Azure OpenAI API, as well as Anthropic models. With a little extra setup, you can also run with open source models like WizardCoder. See the [documentation](https://gpt-engineer.readthedocs.io/en/latest/open_models.html) for example instructions. ## Mission The gpt-engineer community mission is to **maintain tools that coding agent builders can use and facilitate collaboration in the open source community**. If you are interested in contributing to this, we are interested in having you. If you want to see our broader ambitions, check out the [roadmap](https://github.com/gpt-engineer-org/gpt-engineer/blob/main/ROADMAP.md), and join [discord](https://discord.gg/8tcDQ89Ej2) to learn how you can [contribute](.github/CONTRIBUTING.md) to it. gpt-engineer is [governed](https://github.com/gpt-engineer-org/gpt-engineer/blob/main/GOVERNANCE.md) by a board of long-term contributors. If you contribute routinely and have an interest in shaping the future of gpt-engineer, you will be considered for the board. ## Significant contributors ## Example https://github.com/gpt-engineer-org/gpt-engineer/assets/4467025/40d0a9a8-82d0-4432-9376-136df0d57c99 ================================================ FILE: ROADMAP.md ================================================ # Roadmap image This document is a general roadmap guide to the gpt-engineer project's strategic direction. Our goal is to continually improve by focusing on three main pillars: - User Experience, - Technical Features, and - Performance Tracking/Testing. Each pillar is supported by a set of epics, reflecting our major goals and initiatives. ## Tracking Progress with GitHub Projects We are using [GitHub Projects](https://github.com/orgs/gpt-engineer-org/projects/3) to track the progress of our roadmap. Each issue within our project is categorized under one of the main pillars and, in most cases, associated epics. You can check our [Project's README](https://github.com/orgs/gpt-engineer-org/projects/3?pane=info) section to understand better our logic and organization. # How you can help out You can: - Post a "design" as a Google Doc in our [Discord](https://discord.com/channels/1119885301872070706/1120698764445880350), and ask for feedback to address one of the items in the roadmap - Submit PRs to address one of the items in the roadmap - Do a review of someone else's PR and propose next steps (further review, merge, close) 🙌 Volunteer work in any of these will get acknowledged.🙌 ================================================ FILE: TERMS_OF_USE.md ================================================ # Terms of Use Welcome to gpt-engineer! By utilizing this powerful tool, you acknowledge and agree to the following comprehensive Terms of Use. We also encourage you to review the linked [disclaimer of warranty](https://github.com/gpt-engineer-org/gpt-engineer/blob/main/DISCLAIMER.md) for additional information. Both OpenAI, L.L.C. and the dedicated creators behind the remarkable gpt-engineer have implemented a data collection process focused on enhancing the product's capabilities. This endeavor is undertaken with utmost care and dedication to safeguarding user privacy. Rest assured that no information that could be directly attributed to any individual is stored. It's important to be aware that the utilization of natural text inputs, including the 'prompt' and 'feedback' files, may be subject to storage. While it's theoretically possible to establish connections between a person's writing style or content within these files and their real-life identity, please note that the creators of gpt-engineer explicitly assure that such attempts will never be made. For a deeper understanding of OpenAI's overarching terms of use, we encourage you to explore the details available [here](https://openai.com/policies/terms-of-use). Optionally, gpt-engineer collects usage data for the purpose of improving gpt-engineer. Data collection only happens when a consent file called .gpte_consent is present in the gpt-engineer directory. Note that gpt-engineer cannot prevent that data streams passing through gpt-engineer to a third party may be stored by that third party (for example OpenAI). Your engagement with gpt-engineer is an acknowledgment and acceptance of these terms, demonstrating your commitment to using this tool responsibly and within the bounds of ethical conduct. We appreciate your trust and look forward to the exciting possibilities that gpt-engineer can offer in your endeavors. ================================================ FILE: WINDOWS_README.md ================================================ # Windows Setup ## Short version On Windows, follow the standard [README.md](https://github.com/gpt-engineer-org/gpt-engineer/blob/main/README.md), but to set API key do one of: - `set OPENAI_API_KEY=[your api key]` on cmd - `$env:OPENAI_API_KEY="[your api key]"` on powershell ## Full setup guide Choose either **stable** or **development**. For **stable** release: Run `pip install gpt-engineer` in the command line as an administrator Or: 1. Open your web browser and navigate to the Python Package Index (PyPI) website: . 2. On the PyPI page for the gpt-engineer package, locate the "Download files" section. Here you'll find a list of available versions and their corresponding download links. 3. Identify the version of gpt-engineer you want to install and click on the associated download link. This will download the package file (usually a .tar.gz or .whl file) to your computer. 4. Once the package file is downloaded, open your Python development environment or IDE. 5. In your Python development environment, look for an option to install packages or manage dependencies. The exact location and terminology may vary depending on your IDE. For example, in PyCharm, you can go to "File" > "Settings" > "Project: \" > "Python Interpreter" to manage packages. 6. In the package management interface, you should see a list of installed packages. Look for an option to add or install a new package. 7. Click on the "Add Package" or "Install Package" button. 8. In the package installation dialog, choose the option to install from a file or from a local source. 9. Browse and select the downloaded gpt-engineer package file from your computer. For **development**: - `git clone git@github.com:gpt-engineer-org/gpt-engineer.git` - `cd gpt-engineer` - `poetry install` - `poetry shell` to activate the virtual environment ### Setup With an api key from OpenAI: Run `set OPENAI_API_KEY=[your API key]` in the command line Or: 1. In the Start Menu, type to search for "Environment Variables" and click on "Edit the system environment variables". 2. In the System Properties window, click on the "Environment Variables" button. 3. In the Environment Variables window, you'll see two sections: User variables and System variables. 4. To set a user-specific environment variable, select the "New" button under the User variables section. 5. To set a system-wide environment variable, select the "New" button under the System variables section. 6. Enter the variable name "OPENAI_API_KEY" in the "Variable name" field. 7. Enter the variable value (e.g., your API key) in the "Variable value" field. 8. Click "OK" to save the changes. 9. Close any open command prompt or application windows and reopen them for the changes to take effect. Now you can use `%OPENAI_API_KEY%` when prompted to input your key. ### Run - Create an empty folder. If inside the repo, you can: - Run `xcopy /E projects\example projects\my-new-project` in the command line - Or hold CTRL and drag the folder down to create a copy, then rename to fit your project - Fill in the `prompt` file in your new folder - `gpt-engineer projects/my-new-project` - (Note, `gpt-engineer --help` lets you see all available options. For example `--steps use_feedback` lets you improve/fix code in a project) By running gpt-engineer you agree to our [ToS](https://github.com/gpt-engineer-org/gpt-engineer/blob/main/TERMS_OF_USE.md). ### Results - Check the generated files in `projects/my-new-project/workspace` ================================================ FILE: citation.cff ================================================ cff-version: 1.0.0 message: "If you use this software, please cite it as below." authors: - family-names: Osika given-names: Anton title: gpt-engineer version: 0.1.0 date-released: 2023-04-23 repository-code: https://github.com/gpt-engineer-org/gpt-engineer url: https://gpt-engineer.readthedocs.io ================================================ FILE: docker/Dockerfile ================================================ # Stage 1: Builder stage FROM python:3.11-slim AS builder RUN apt-get update && apt-get install -y --no-install-recommends \ tk \ tcl \ curl \ git \ && rm -rf /var/lib/apt/lists/* WORKDIR /app COPY . . RUN pip install --no-cache-dir -e . # Stage 2: Final stage FROM python:3.11-slim WORKDIR /app COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages COPY --from=builder /usr/local/bin /usr/local/bin COPY --from=builder /usr/bin /usr/bin COPY --from=builder /app . COPY docker/entrypoint.sh . ENTRYPOINT ["bash", "/app/entrypoint.sh"] ================================================ FILE: docker/README.md ================================================ # Getting Started Using Docker This guide provides step-by-step instructions on how to set up and run the Docker environment for your GPT-Engineer project. ## Prerequisites - Docker installed on your machine. - Git (for cloning the repository). ## Setup Instructions ### Using Docker CLI 1. **Clone the Repository** ```bash git clone https://github.com/gpt-engineer-org/gpt-engineer.git cd gpt-engineer ``` 2. **Build the Docker Image** ```bash docker build --rm -t gpt-engineer -f docker/Dockerfile . ``` 3. **Run the Docker Container** ```bash docker run -it --rm -e OPENAI_API_KEY="YOUR_OPENAI_KEY" -v ./your-project:/project gpt-engineer ``` Replace `YOUR_OPENAI_KEY` with your actual OpenAI API key. The `-v` flag mounts your local `your-project` directory inside the container. Replace this with your actual project directory. Ensure this directory contains all necessary files, including the `prompt` file. ### Using Docker Compose 1. **Clone the Repository** (if not already done) ```bash git clone https://github.com/gpt-engineer-org/gpt-engineer.git cd gpt-engineer ``` 2. **Build and Run using Docker Compose** ```bash docker-compose -f docker-compose.yml build docker-compose run --rm gpt-engineer ``` Set the `OPENAI_API_KEY` in the `docker/docker-compose.yml` using an `.env` file or as an environment variable. Mount your project directory to the container using volumes, e.g., `"./projects/example:/project"` where `./projects/example` is the path to your project directory. 3. **Another alternative using Docker Compose** Since there is only one `docker-compose.yml` file, you could run it without the -f option. - `docker compose up -d --build` - To build and start the containers defined in your `docker-compose.yml` file in detached mode - `docker compose up -d` - To start the containers defined in your `docker-compose.yml` file in detached mode - `docker compose down` - To stop and remove all containers, networks, and volumes associated with the `docker-compose.yml` - `docker compose restart` - To restart the containers defined in the `docker-compose.yml` file ## Debugging To facilitate debugging, you can run a shell inside the built Docker image: ```bash docker run -it --entrypoint /bin/bash gpt-engineer ``` This opens a shell inside the Docker container, allowing you to execute commands and inspect the environment manually. ================================================ FILE: docker/entrypoint.sh ================================================ #!/usr/bin/env bash # -*- coding: utf-8 -*- project_dir="/project" # Run the gpt engineer script gpt-engineer $project_dir "$@" # Patch the permissions of the generated files to be owned by nobody except prompt file find "$project_dir" -mindepth 1 -maxdepth 1 ! -path "$project_dir/prompt" -exec chown -R nobody:nogroup {} + -exec chmod -R 777 {} + ================================================ FILE: docker-compose.yml ================================================ services: gpt-engineer: build: context: . dockerfile: docker/Dockerfile stdin_open: true tty: true # Set the API key from the .env file env_file: - .env ## OR set the API key directly # environment: # - OPENAI_API_KEY=YOUR_API_KEY image: gpt-engineer volumes: - ./projects/example:/project ================================================ FILE: docs/Makefile ================================================ # Minimal makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = python -msphinx SPHINXPROJ = gpt_engineer SOURCEDIR = . BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) ================================================ FILE: docs/api_reference.rst ================================================ .. _api_reference: ============= API Reference ============= :mod:`gpt_engineer.applications`: Applications =============================================== .. automodule:: gpt_engineer.applications :no-members: :no-inherited-members: Classes -------------- .. currentmodule:: gpt_engineer .. autosummary:: :toctree: applications :template: class.rst applications.cli.cli_agent.CliAgent applications.cli.file_selector.DisplayablePath Functions -------------- .. currentmodule:: gpt_engineer .. autosummary:: :toctree: applications applications.cli.collect.collect_and_send_human_review applications.cli.collect.collect_learnings applications.cli.collect.send_learning applications.cli.learning.ask_collection_consent applications.cli.learning.ask_for_valid_input applications.cli.learning.check_collection_consent applications.cli.learning.extract_learning applications.cli.learning.get_session applications.cli.learning.human_review_input applications.cli.main.get_preprompts_path applications.cli.main.load_env_if_needed applications.cli.main.load_prompt applications.cli.main.main :mod:`gpt_engineer.benchmark`: Benchmark ========================================= .. automodule:: gpt_engineer.benchmark :no-members: :no-inherited-members: Functions -------------- .. currentmodule:: gpt_engineer .. autosummary:: :toctree: benchmark benchmark.__main__.get_agent benchmark.__main__.main benchmark.benchmarks.gpteng.eval_tools.assert_exists_in_source_code benchmark.benchmarks.gpteng.eval_tools.check_evaluation_component benchmark.benchmarks.gpteng.eval_tools.check_language benchmark.benchmarks.gpteng.eval_tools.run_code_class_has_property benchmark.benchmarks.gpteng.eval_tools.run_code_class_has_property_w_value benchmark.benchmarks.gpteng.eval_tools.run_code_eval_function benchmark.benchmarks.gpteng.load.eval_to_task benchmark.benchmarks.gpteng.load.expect_to_assertion benchmark.benchmarks.gpteng.load.load_gpteng benchmark.benchmarks.gptme.load.load_gptme benchmark.benchmarks.load.get_benchmark benchmark.run.print_results benchmark.run.run :mod:`gpt_engineer.core`: Core =============================== .. automodule:: gpt_engineer.core :no-members: :no-inherited-members: Classes -------------- .. currentmodule:: gpt_engineer .. autosummary:: :toctree: core :template: class.rst core.base_agent.BaseAgent core.base_execution_env.BaseExecutionEnv core.default.disk_execution_env.DiskExecutionEnv core.default.disk_memory.DiskMemory core.default.simple_agent.SimpleAgent core.files_dict.FilesDict core.version_manager.BaseVersionManager Functions -------------- .. currentmodule:: gpt_engineer .. autosummary:: :toctree: core core.ai.serialize_messages core.chat_to_files.apply_diffs core.chat_to_files.chat_to_files_dict core.chat_to_files.parse_diff_block core.chat_to_files.parse_diffs core.chat_to_files.parse_hunk_header core.default.paths.memory_path core.default.paths.metadata_path core.default.simple_agent.default_config_agent core.default.steps.curr_fn core.default.steps.execute_entrypoint core.default.steps.gen_code core.default.steps.gen_entrypoint core.default.steps.improve core.default.steps.salvage_correct_hunks core.default.steps.setup_sys_prompt core.default.steps.setup_sys_prompt_existing_code core.diff.count_ratio core.diff.is_similar core.files_dict.file_to_lines_dict :mod:`gpt_engineer.tools`: Tools ================================= .. automodule:: gpt_engineer.tools :no-members: :no-inherited-members: Functions -------------- .. currentmodule:: gpt_engineer .. autosummary:: :toctree: tools tools.custom_steps.clarified_gen tools.custom_steps.get_platform_info tools.custom_steps.lite_gen tools.custom_steps.self_heal ================================================ FILE: docs/code_conduct_link.rst ================================================ .. include:: ../.github/CODE_OF_CONDUCT.md :parser: myst_parser.sphinx_ ================================================ FILE: docs/conf.py ================================================ #!/usr/bin/env python # # file_processor documentation build configuration file, created by # sphinx-quickstart on Fri Jun 9 13:47:02 2017. # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. # If extensions (or modules to document with autodoc) are in another # directory, add these directories to sys.path here. If the directory is # relative to the documentation root, use os.path.abspath to make it # absolute, like shown here. # import os import sys from pathlib import Path import toml sys.path.insert(0, os.path.abspath("..")) ROOT_DIR = Path(__file__).parents[1].absolute() with open("../pyproject.toml") as f: data = toml.load(f) # The master toctree document. master_doc = "index" # General information about the project. project = data["tool"]["poetry"]["name"] copyright = "2023 Anton Osika" author = " Anton Osika & Contributors" # The version info for the project you're documenting, acts as replacement # for |version| and |release|, also used in various other places throughout # the built documents. # # The short X.Y version. version = data["tool"]["poetry"]["version"] # The full version, including alpha/beta/rc tags. release = data["tool"]["poetry"]["version"] # -- General configuration --------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. # # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ "sphinx.ext.autodoc", "sphinx.ext.autodoc.typehints", "sphinx.ext.autosummary", "sphinx.ext.napoleon", "sphinx.ext.viewcode", "sphinx_copybutton", "myst_parser", "IPython.sphinxext.ipython_console_highlighting", ] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: source_suffix = [".rst", ".md"] autodoc_pydantic_model_show_json = False autodoc_pydantic_field_list_validators = False autodoc_pydantic_config_members = False autodoc_pydantic_model_show_config_summary = False autodoc_pydantic_model_show_validator_members = False autodoc_pydantic_model_show_validator_summary = False autodoc_pydantic_model_signature_prefix = "class" autodoc_pydantic_field_signature_prefix = "param" autodoc_member_order = "groupwise" autoclass_content = "both" autodoc_typehints_format = "short" autodoc_default_options = { "members": True, "show-inheritance": True, "inherited-members": "BaseModel", "undoc-members": False, } # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] # source_suffix = '.rst' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = "en" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # The name of the Pygments (syntax highlighting) style to use. pygments_style = "sphinx" # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False # -- Options for HTML output ------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # # html_theme = 'alabaster' html_theme = "sphinx_rtd_theme" # Theme options are theme-specific and customize the look and feel of a # theme further. For a list of options available for each theme, see the # documentation. # # html_theme_options = {} # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". # html_static_path = ["_static"] # -- Options for HTMLHelp output --------------------------------------- # Output file base name for HTML help builder. htmlhelp_basename = "gpt_engineerdoc" # -- Options for LaTeX output ------------------------------------------ latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # # 'preamble': '', # Latex figure (float) alignment # # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass # [howto, manual, or own class]). latex_documents = [ (master_doc, "gpt_engineer.tex", "GPT-ENgineer Documentation", "manual"), ] # -- Options for manual page output ------------------------------------ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [(master_doc, "gpt_engineer", "GPT-Engineer Documentation", [author], 1)] # -- Options for Texinfo output ---------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ( master_doc, "gpt_engineer", "GPT-Engineer Documentation", author, "gpt_engineer", "One line description of project.", "Miscellaneous", ), ] # generate autosummary even if no references autosummary_generate = True myst_enable_extensions = [ "colon_fence", ] myst_all_links_external = True ================================================ FILE: docs/contributing_link.rst ================================================ .. include:: ../.github/CONTRIBUTING.md :parser: myst_parser.sphinx_ ================================================ FILE: docs/create_api_rst.py ================================================ """Script for auto-generating api_reference.rst""" import glob import re from pathlib import Path ROOT_DIR = Path(__file__).parents[1].absolute() print(ROOT_DIR) PKG_DIR = ROOT_DIR / "gpt_engineer" WRITE_FILE = Path(__file__).parent / "api_reference.rst" def load_members() -> dict: members: dict = {} for py in glob.glob(str(PKG_DIR) + "/**/*.py", recursive=True): module = py[len(str(PKG_DIR)) + 1 :].replace(".py", "").replace("/", ".") top_level = module.split(".")[0] if top_level not in members: members[top_level] = {"classes": [], "functions": []} with open(py, "r") as f: for line in f.readlines(): cls = re.findall(r"^class ([^_].*)\(", line) members[top_level]["classes"].extend([module + "." + c for c in cls]) func = re.findall(r"^def ([^_].*)\(", line) afunc = re.findall(r"^async def ([^_].*)\(", line) func_strings = [module + "." + f for f in func + afunc] members[top_level]["functions"].extend(func_strings) return members def construct_doc(members: dict) -> str: full_doc = """\ .. _api_reference: ============= API Reference ============= """ for module, _members in sorted(members.items(), key=lambda kv: kv[0]): classes = _members["classes"] functions = _members["functions"] if not (classes or functions): continue module_title = module.replace("_", " ").title() if module_title == "Llms": module_title = "LLMs" section = f":mod:`gpt_engineer.{module}`: {module_title}" full_doc += f"""\ {section} {'=' * (len(section) + 1)} .. automodule:: gpt_engineer.{module} :no-members: :no-inherited-members: """ if classes: cstring = "\n ".join(sorted(classes)) full_doc += f"""\ Classes -------------- .. currentmodule:: gpt_engineer .. autosummary:: :toctree: {module} :template: class.rst {cstring} """ if functions: fstring = "\n ".join(sorted(functions)) full_doc += f"""\ Functions -------------- .. currentmodule:: gpt_engineer .. autosummary:: :toctree: {module} {fstring} """ return full_doc def main() -> None: members = load_members() full_doc = construct_doc(members) with open(WRITE_FILE, "w") as f: f.write(full_doc) if __name__ == "__main__": main() ================================================ FILE: docs/disclaimer_link.rst ================================================ .. include:: ../DISCLAIMER.md :parser: myst_parser.sphinx_ ================================================ FILE: docs/docs_building.md ================================================ Building Docs with Sphinx ========================= This example shows a basic Sphinx docs project with Read the Docs. This project is using `sphinx` with `readthedocs` project template. Some useful links are given below to lear and contribute in the project. 📚 [docs/](https://www.sphinx-doc.org/en/master/usage/quickstart.html)
A basic Sphinx project lives in `docs/`, it was generated using Sphinx defaults. All the `*.rst` & `*.md` make up sections in the documentation. Both `.rst` and `.md` formats are supported in this project ⚙️ [.readthedocs.yaml](https://docs.readthedocs.io/en/stable/config-file/v2.html)
Read the Docs Build configuration is stored in `.readthedocs.yaml`. Example Project usage --------------------- ``Poetry`` is the package manager for ``gpt-engineer``. In order to build documentation, we have to add docs requirements in development environment. This project has a standard readthedocs layout which is built by Read the Docs almost the same way that you would build it locally (on your own laptop!). You can build and view this documentation project locally - we recommend that you activate a ``poetry shell``. Update ``repository_stats.md`` file under ``docs/intro`` ```console # Install required Python dependencies (MkDocs etc.) poetry install cd docs/ # Create the `api_reference.rst` python create_api_rst.py # Build the docs make html ## Alternatively, to rebuild the docs on changes with live-reload in the browser sphinx-autobuild . _build/html ``` Project Docs Structure ---------------------- If you are new to Read the Docs, you may want to refer to the [Read the Docs User documentation](https://docs.readthedocs.io/). Below is the rundown of documentation structure for `pandasai`, you need to know: 1. place your `docs/` folder alongside your Python project. 2. copy `.readthedocs.yaml` and the `docs/` folder into your project root. 3. `docs/api_reference.rst` contains the API documentation created using `docstring`. Run the `create_api_rst.py` to update the API reference file. 4. Project is using standard Google Docstring Style. 5. Rebuild the documentation locally to see that it works. 6. Documentation are hosted on [Read the Docs tutorial](https://docs.readthedocs.io/en/stable/tutorial/) Read the Docs tutorial ---------------------- To get started with Read the Docs, you may also refer to the [Read the Docs tutorial](https://docs.readthedocs.io/en/stable/tutorial/). I With every release, build the documentation manually. ================================================ FILE: docs/examples/open_llms/README.md ================================================ # Test that the Open LLM is running First start the server by using only CPU: ```bash export model_path="TheBloke/CodeLlama-13B-GGUF/codellama-13b.Q8_0.gguf" python -m llama_cpp.server --model $model_path ``` Or with GPU support (recommended): ```bash python -m llama_cpp.server --model TheBloke/CodeLlama-13B-GGUF/codellama-13b.Q8_0.gguf --n_gpu_layers 1 ``` If you have more `GPU` layers available set `--n_gpu_layers` to the higher number. To find the amount of available run the above command and look for `llm_load_tensors: offloaded 1/41 layers to GPU` in the output. ## Test API call Set the environment variables: ```bash export OPENAI_API_BASE="http://localhost:8000/v1" export OPENAI_API_KEY="sk-xxx" export MODEL_NAME="CodeLlama" ```` Then ping the model via `python` using `OpenAI` API: ```bash python examples/open_llms/openai_api_interface.py ``` If you're not using `CodeLLama` make sure to change the `MODEL_NAME` parameter. Or using `curl`: ```bash curl --request POST \ --url http://localhost:8000/v1/chat/completions \ --header "Content-Type: application/json" \ --data '{ "model": "CodeLlama", "prompt": "Who are you?", "max_tokens": 60}' ``` If this works also make sure that `langchain` interface works since that's how `gpte` interacts with LLMs. ## Langchain test ```bash export MODEL_NAME="CodeLlama" python examples/open_llms/langchain_interface.py ``` That's it 🤓 time to go back [to](/docs/open_models.md#running-the-example) and give `gpte` a try. ================================================ FILE: docs/examples/open_llms/langchain_interface.py ================================================ import os from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler from langchain_openai import ChatOpenAI model = ChatOpenAI( model=os.getenv("MODEL_NAME"), temperature=0.1, callbacks=[StreamingStdOutCallbackHandler()], streaming=True, ) prompt = ( "Provide me with only the code for a simple python function that sums two numbers." ) model.invoke(prompt) ================================================ FILE: docs/examples/open_llms/openai_api_interface.py ================================================ import os from openai import OpenAI client = OpenAI( base_url=os.getenv("OPENAI_API_BASE"), api_key=os.getenv("OPENAI_API_KEY") ) response = client.chat.completions.create( model=os.getenv("MODEL_NAME"), messages=[ { "role": "user", "content": "Provide me with only the code for a simple python function that sums two numbers.", }, ], temperature=0.7, max_tokens=200, ) print(response.choices[0].message.content) ================================================ FILE: docs/index.rst ================================================ Welcome to GPT-ENGINEER's Documentation ======================================= .. toctree:: :maxdepth: 2 :caption: GET STARTED: introduction.md installation quickstart .. toctree:: :maxdepth: 2 :caption: USER GUIDES: windows_readme_link open_models.md tracing_debugging.md .. toctree:: :maxdepth: 2 :caption: CONTRIBUTE: contributing_link roadmap_link code_conduct_link disclaimer_link docs_building.md terms_link .. toctree:: :maxdepth: 2 :caption: PACKAGE API: api_reference Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` ================================================ FILE: docs/installation.rst ================================================ .. highlight:: shell ============ Installation ============ Stable release -------------- To install ``gpt-engineer``, run this command in your terminal: .. code-block:: console $ python -m pip install gpt-engineer This is the preferred method to install ``gpt-engineer``, as it will always install the most recent stable release. If you don't have `pip`_ installed, this `Python installation guide`_ can guide you through the process. .. note:: When reporting bugs, please specify your installation method (using `pip install` or by building the repository) in the "Installation Method" section of the bug report template. .. _pip: https://pip.pypa.io .. _Python installation guide: http://docs.python-guide.org/en/latest/starting/installation/ From sources ------------ The sources for ``gpt-engineer`` can be downloaded from the `Github repo`_. You can either clone the public repository: .. code-block:: console $ git clone https://github.com/gpt-engineer-org/gpt-engineer.git Once you have a copy of the source, you can install it with: .. code-block:: console $ cd gpt-engineer $ poetry install $ poetry shell .. _Github repo: https://github.com/gpt-engineer-org/gpt-engineer.git Troubleshooting --------------- For mac and linux system, there are sometimes slim python installations that do not include the ``gpt-engineer`` requirement tkinter, which is a standard library and thus not pip installable. To install tkinter on mac, you can for example use brew: .. code-block:: console $ brew install python-tk On debian-based linux systems you can use: .. code-block:: console $ sudo apt-get install python3-tk ================================================ FILE: docs/introduction.md ================================================ # Introduction ``gpt-engineer`` is a project that uses LLMs (such as GPT-4) to automate the process of software engineering. It includes several Python scripts that interact with the LLM to generate code, clarify requirements, generate specifications, and more.
## Get started [Here’s](/en/latest/installation.html) how to install ``gpt-engineer``, set up your environment, and start building. We recommend following our [Quickstart](/en/latest/quickstart.html) guide to familiarize yourself with the framework by building your first application with ``gpt-engineer``.
## Example You can find an example of the project in action here. ================================================ FILE: docs/make.bat ================================================ @ECHO OFF pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=python -msphinx ) set SOURCEDIR=. set BUILDDIR=_build set SPHINXPROJ=file_processor if "%1" == "" goto help %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. echo.The Sphinx module was not found. Make sure you have Sphinx installed, echo.then set the SPHINXBUILD environment variable to point to the full echo.path of the 'sphinx-build' executable. Alternatively you may add the echo.Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% goto end :help %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% :end popd ================================================ FILE: docs/open_models.md ================================================ Using with open/local models ============================ **Use `gpte` first with OpenAI models to get a feel for the `gpte` tool.** **Then go play with experimental Open LLMs 🐉 support and try not to get 🔥!!** At the moment the best option for coding is still the use of `gpt-4` models provided by OpenAI. But open models are catching up and are a good free and privacy-oriented alternative if you possess the proper hardware. You can integrate `gpt-engineer` with open-source models by leveraging an OpenAI-compatible API. We provide the minimal and cleanest solution below. What is described is not the only way to use open/local models, but the one we tested and would recommend to most users. More details on why the solution below is recommended in [this blog post](https://zigabrencic.com/blog/2024-02-21). Setup ----- For inference engine we recommend for the users to use [llama.cpp](https://github.com/ggerganov/llama.cpp) with its `python` bindings `llama-cpp-python`. We choose `llama.cpp` because: - 1.) It supports the largest amount of hardware acceleration backends. - 2.) It supports the diverse set of open LLMs. - 3.) Is written in `python` and directly on top of `llama.cpp` inference engine. - 4.) Supports the `openAI` API and `langchain` interface. To install `llama-cpp-python` follow the official [installation docs](https://llama-cpp-python.readthedocs.io/en/latest/) and [those docs](https://llama-cpp-python.readthedocs.io/en/latest/install/macos/) for MacOS with Metal support. If you want to benefit from proper hardware acceleration on your machine make sure to set up the proper compiler flags before installing your package. - `linux`: `CMAKE_ARGS="-DLLAMA_BLAS=ON -DLLAMA_BLAS_VENDOR=OpenBLAS"` - `macos` with Metal support: `CMAKE_ARGS="-DLLAMA_METAL=on"` - `windows`: `$env:CMAKE_ARGS = "-DLLAMA_BLAS=ON -DLLAMA_BLAS_VENDOR=OpenBLAS"` This will enable the `pip` installer to compile the `llama.cpp` with the proper hardware acceleration backend. Then run: ```bash pip install llama-cpp-python ``` For our use case we also need to set up the web server that `llama-cpp-python` library provides. To install: ```bash pip install 'llama-cpp-python[server]' ``` For detailed use consult the [`llama-cpp-python` docs](https://llama-cpp-python.readthedocs.io/en/latest/server/). Before we proceed we need to obtain the model weights in the `gguf` format. That should be a single file on your disk. In case you have weights in other formats check the `llama-cpp-python` docs for conversion to `gguf` format. Models in other formats `ggml`, `.safetensors`, etc. won't work without prior conversion to `gguf` file format with the solution described below! Which open model to use? ================== Your best choice would be: - CodeLlama 70B - Mixtral 8x7B We are still testing this part, but the larger the model you can run the better. Sure the responses might be slower in terms of (token/s), but code quality will be higher. For testing that the open LLM `gpte` setup works we recommend starting with a smaller model. You can download weights of [CodeLlama-13B-GGUF by the `TheBloke`](https://huggingface.co/TheBloke/CodeLlama-13B-GGUF) choose the largest model version you can run (for example `Q6_K`), since quantisation will degrade LLM performance. Feel free to try out larger models on your hardware and see what happens. Running the Example ================== To see that your setup works check [test open LLM setup](examples/test_open_llm/README.md). If above tests work proceed 😉 For checking that `gpte` works with the `CodeLLama` we recommend for you to create a project with `prompt` file content: ``` Write a python script that sums up two numbers. Provide only the `sum_two_numbers` function and nothing else. Provide two tests: assert(sum_two_numbers(100, 10) == 110) assert(sum_two_numbers(10.1, 10) == 20.1) ``` Now run the LLM in separate terminal: ```bash python -m llama_cpp.server --model $model_path --n_batch 256 --n_gpu_layers 30 ``` Then in another terminal window set the following environment variables: ```bash export OPENAI_API_BASE="http://localhost:8000/v1" export OPENAI_API_KEY="sk-xxx" export MODEL_NAME="CodeLLama" export LOCAL_MODEL=true ``` And run `gpt-engineer` with the following command: ```bash gpte $MODEL_NAME --lite --temperature 0.1 ``` The `--lite` mode is needed for now since open models for some reason behave worse with too many instructions at the moment. Temperature is set to `0.1` to get consistent best possible results. That's it. *If sth. doesn't work as expected, or you figure out how to improve the open LLM support please let us know.* Using Open Router models ================== In case you don't posses the hardware to run local LLM's yourself you can use the hosting on [Open Router](https://openrouter.ai) and pay as you go for the tokens. To set it up you need to Sign In and load purchase 💰 the LLM credits. Pricing per token is different for (each model](https://openrouter.ai/models), but mostly cheaper then Open AI. Then create the API key. To for example use [Meta: Llama 3 8B Instruct (extended)](https://openrouter.ai/models/meta-llama/llama-3-8b-instruct:extended) with `gpte` we need to set: ```bash export OPENAI_API_BASE="https://openrouter.ai/api/v1" export OPENAI_API_KEY="sk-key-from-open-router" export MODEL_NAME="meta-llama/llama-3-8b-instruct:extended" export LOCAL_MODEL=true ``` ```bash gpte $MODEL_NAME --lite --temperature 0.1 ``` Using Azure models ================== You set your Azure OpenAI key: - `export OPENAI_API_KEY=[your api key]` Then you call `gpt-engineer` with your service endpoint `--azure https://aoi-resource-name.openai.azure.com` and set your deployment name (which you created in the Azure AI Studio) as the model name (last `gpt-engineer` argument). Example: `gpt-engineer --azure https://myairesource.openai.azure.com ./projects/example/ my-gpt4-project-name` ================================================ FILE: docs/quickstart.rst ================================================ ========== Quickstart ========== Installation ============ To install LangChain run: .. code-block:: console $ python -m pip install gpt-engineer For more details, see our [Installation guide](/instllation.html). Setup API Key ============= Choose one of the following: - Export env variable (you can add this to ``.bashrc`` so that you don't have to do it each time you start the terminal) .. code-block:: console $ export OPENAI_API_KEY=[your api key] - Add it to the ``.env`` file: - Create a copy of ``.env.template`` named ``.env`` - Add your ``OPENAI_API_KEY`` in .env - If you want to use a custom model, visit our docs on `using open models and azure models <./open_models.html>`_. - To set API key on windows check the `Windows README <./windows_readme_link.html>`_. Building with ``gpt-engineer`` ============================== Create new code (default usage) ------------------------------- - Create an empty folder for your project anywhere on your computer - Create a file called ``prompt`` (no extension) inside your new folder and fill it with instructions - Run ``gpte `` with a relative path to your folder - For example, if you create a new project inside the gpt-engineer ``/projects`` directory: .. code-block:: console $ gpte projects/my-new-project Improve Existing Code --------------------- - Locate a folder with code which you want to improve anywhere on your computer - Create a file called ``prompt`` (no extension) inside your new folder and fill it with instructions for how you want to improve the code - Run ``gpte -i`` with a relative path to your folder - For example, if you want to run it against an existing project inside the gpt-engineer ``/projects`` directory: .. code-block:: console $ gpte projects/my-old-project -i By running ``gpt-engineer`` you agree to our `terms <./terms_link.html>`_. To **run in the browser** you can simply: .. image:: https://github.com/codespaces/badge.svg :target: https://github.com/gpt-engineer-org/gpt-engineer/codespaces ================================================ FILE: docs/roadmap_link.rst ================================================ .. include:: ../ROADMAP.md :parser: myst_parser.sphinx_ ================================================ FILE: docs/terms_link.rst ================================================ .. include:: ../TERMS_OF_USE.md :parser: myst_parser.sphinx_ ================================================ FILE: docs/tracing_debugging.md ================================================ Tracing and Debugging with Weights and Biases ============================ ## How to store results in Weights & Biases W&B Prompts is a suite of LLMOps tools built for the development of LLM-powered applications. Use W&B Prompts to visualize and inspect the execution flow of your LLMs, analyze the inputs and outputs of your LLMs, view the intermediate results and securely store and manage your prompts and LLM chain configurations. Read more at https://docs.wandb.ai/guides/prompts ```shell $ export WANDB_API_KEY="YOUR-KEY" $ export LANGCHAIN_WANDB_TRACING=true ``` Sign up for free at https://wandb.ai Debug and trace the execution of the AI generated code to compare across different experiments with `gpt-engineer` and related prompts ![](https://drive.google.com/uc?id=10wuLwyPbH00CoESsS2Q2q6mkdrtS91jd) Automatically capture and save terminal `stdout` to one easily accessible and shareable webpage ![](https://drive.google.com/uc?id=1gVva7ZfpwbTSBsnNvId6iq09Gw5ETOks) ================================================ FILE: docs/windows_readme_link.rst ================================================ .. include:: ../WINDOWS_README.md :parser: myst_parser.sphinx_ ================================================ FILE: gpt_engineer/__init__.py ================================================ # Adding convenience imports to the package # from gpt_engineer.tools import code_vector_repository # from gpt_engineer.core.default import on_disk_repository ================================================ FILE: gpt_engineer/applications/__init__.py ================================================ ================================================ FILE: gpt_engineer/applications/cli/__init__.py ================================================ ================================================ FILE: gpt_engineer/applications/cli/cli_agent.py ================================================ """ This module provides the CliAgent class which manages the lifecycle of code generation and improvement using an AI model. It includes functionalities to initialize code generation, improve existing code, and process the code through various steps defined in the step bundle. """ from typing import Callable, Optional, TypeVar # from gpt_engineer.core.default.git_version_manager import GitVersionManager from gpt_engineer.core.ai import AI from gpt_engineer.core.base_agent import BaseAgent from gpt_engineer.core.base_execution_env import BaseExecutionEnv from gpt_engineer.core.base_memory import BaseMemory from gpt_engineer.core.default.disk_execution_env import DiskExecutionEnv from gpt_engineer.core.default.disk_memory import DiskMemory from gpt_engineer.core.default.paths import PREPROMPTS_PATH from gpt_engineer.core.default.steps import ( execute_entrypoint, gen_code, gen_entrypoint, improve_fn, ) from gpt_engineer.core.files_dict import FilesDict from gpt_engineer.core.preprompts_holder import PrepromptsHolder from gpt_engineer.core.prompt import Prompt CodeGenType = TypeVar("CodeGenType", bound=Callable[[AI, str, BaseMemory], FilesDict]) CodeProcessor = TypeVar( "CodeProcessor", bound=Callable[[AI, BaseExecutionEnv, FilesDict], FilesDict] ) ImproveType = TypeVar( "ImproveType", bound=Callable[[AI, str, FilesDict, BaseMemory], FilesDict] ) class CliAgent(BaseAgent): """ The `CliAgent` class is responsible for managing the lifecycle of code generation and improvement using an AI model. It orchestrates the generation of new code and the improvement of existing code based on given prompts and utilizes a memory system and execution environment for processing. Parameters ---------- memory : BaseMemory An instance of a class that adheres to the BaseMemory interface, used for storing and retrieving information during the code generation process. execution_env : BaseExecutionEnv An instance of a class that adheres to the BaseExecutionEnv interface, used for executing code and managing the execution environment. ai : AI, optional An instance of the AI class that manages calls to the language model. If not provided, a default instance is created. code_gen_fn : CodeGenType, optional A callable that takes an AI instance, a prompt, and a memory instance to generate code. Defaults to the `gen_code` function. improve_fn : ImproveType, optional A callable that takes an AI instance, a prompt, a FilesDict instance, and a memory instance to improve code. Defaults to the `improve` function. process_code_fn : CodeProcessor, optional A callable that takes an AI instance, an execution environment, and a FilesDict instance to process code. Defaults to the `execute_entrypoint` function. preprompts_holder : PrepromptsHolder, optional An instance of PrepromptsHolder that manages preprompt templates. If not provided, a default instance is created using the PREPROMPTS_PATH. Attributes ---------- memory : BaseMemory The memory instance where the agent stores and retrieves information. execution_env : BaseExecutionEnv The execution environment instance where the agent executes and manages code. ai : AI The AI instance used for interacting with the language model. code_gen_fn : CodeGenType The function used for generating code. improve_fn : ImproveType The function used for improving code. process_code_fn : CodeProcessor The function used for processing code. preprompts_holder : PrepromptsHolder The holder for preprompt templates. """ def __init__( self, memory: BaseMemory, execution_env: BaseExecutionEnv, ai: AI = None, code_gen_fn: CodeGenType = gen_code, improve_fn: ImproveType = improve_fn, process_code_fn: CodeProcessor = execute_entrypoint, preprompts_holder: PrepromptsHolder = None, ): self.memory = memory self.execution_env = execution_env self.ai = ai or AI() self.code_gen_fn = code_gen_fn self.process_code_fn = process_code_fn self.improve_fn = improve_fn self.preprompts_holder = preprompts_holder or PrepromptsHolder(PREPROMPTS_PATH) @classmethod def with_default_config( cls, memory: DiskMemory, execution_env: DiskExecutionEnv, ai: AI = None, code_gen_fn: CodeGenType = gen_code, improve_fn: ImproveType = improve_fn, process_code_fn: CodeProcessor = execute_entrypoint, preprompts_holder: PrepromptsHolder = None, diff_timeout=3, ): """ Creates a new instance of CliAgent with default configurations for memory, execution environment, AI, and other functional parameters. Parameters ---------- memory : DiskMemory An instance of DiskMemory for storing and retrieving information. execution_env : DiskExecutionEnv An instance of DiskExecutionEnv for executing code. ai : AI, optional An instance of AI for interacting with the language model. Defaults to None, which will create a new AI instance. code_gen_fn : CodeGenType, optional A function for generating code. Defaults to `gen_code`. improve_fn : ImproveType, optional A function for improving code. Defaults to `improve`. process_code_fn : CodeProcessor, optional A function for processing code. Defaults to `execute_entrypoint`. preprompts_holder : PrepromptsHolder, optional An instance of PrepromptsHolder for managing preprompt templates. Defaults to None, which will create a new PrepromptsHolder instance using PREPROMPTS_PATH. Returns ------- CliAgent An instance of CliAgent configured with the provided or default parameters. """ return cls( memory=memory, execution_env=execution_env, ai=ai, code_gen_fn=code_gen_fn, process_code_fn=process_code_fn, improve_fn=improve_fn, preprompts_holder=preprompts_holder or PrepromptsHolder(PREPROMPTS_PATH), ) def init(self, prompt: Prompt) -> FilesDict: """ Generates a new piece of code using the AI and step bundle based on the provided prompt. Parameters ---------- prompt : str A string prompt that guides the code generation process. Returns ------- FilesDict An instance of the `FilesDict` class containing the generated code. """ files_dict = self.code_gen_fn( self.ai, prompt, self.memory, self.preprompts_holder ) entrypoint = gen_entrypoint( self.ai, prompt, files_dict, self.memory, self.preprompts_holder ) combined_dict = {**files_dict, **entrypoint} files_dict = FilesDict(combined_dict) files_dict = self.process_code_fn( self.ai, self.execution_env, files_dict, preprompts_holder=self.preprompts_holder, prompt=prompt, memory=self.memory, ) return files_dict def improve( self, files_dict: FilesDict, prompt: Prompt, execution_command: Optional[str] = None, diff_timeout=3, ) -> FilesDict: """ Improves an existing piece of code using the AI and step bundle based on the provided prompt. Parameters ---------- files_dict : FilesDict An instance of `FilesDict` containing the code to be improved. prompt : str A string prompt that guides the code improvement process. execution_command : str, optional An optional command to execute the code. If not provided, the default execution command is used. Returns ------- FilesDict An instance of the `FilesDict` class containing the improved code. """ files_dict = self.improve_fn( self.ai, prompt, files_dict, self.memory, self.preprompts_holder, diff_timeout=diff_timeout, ) # entrypoint = gen_entrypoint( # self.ai, prompt, files_dict, self.memory, self.preprompts_holder # ) # combined_dict = {**files_dict, **entrypoint} # files_dict = FilesDict(combined_dict) # files_dict = self.process_code_fn( # self.ai, # self.execution_env, # files_dict, # preprompts_holder=self.preprompts_holder, # prompt=prompt, # memory=self.memory, # ) return files_dict ================================================ FILE: gpt_engineer/applications/cli/collect.py ================================================ """ Module `collect` - Data Handling and RudderStack Integration This module provides functionalities to handle and send learning data to RudderStack for the purpose of analysis and to improve the gpt-engineer system. The data is sent only when the user gives consent to share. Functions: send_learning(learning): Sends learning data to RudderStack. collect_learnings(prompt, model, temperature, config, memory, review): Processes and sends learning data. collect_and_send_human_review(prompt, model, temperature, config, memory): Collects human feedback and sends it. Dependencies: hashlib: For generating SHA-256 hash. typing: For type annotations. gpt_engineer.core: Core functionalities of gpt-engineer. gpt_engineer.cli.learning: Handles the extraction of learning data. Notes: Data sent to RudderStack is not shared with third parties and is used solely to improve gpt-engineer and allow it to handle a broader range of use cases. Consent logic is in gpt_engineer/learning.py. """ from typing import Tuple from gpt_engineer.applications.cli.learning import ( Learning, Review, extract_learning, human_review_input, ) from gpt_engineer.core.default.disk_memory import DiskMemory from gpt_engineer.core.prompt import Prompt def send_learning(learning: Learning): """ Send the learning data to RudderStack for analysis. Parameters ---------- learning : Learning An instance of the Learning class containing the data to be sent. Notes ----- This function is only called if consent is given to share data. Data is not shared to a third party. It is used with the sole purpose of improving gpt-engineer, and letting it handle more use cases. Consent logic is in gpt_engineer/learning.py. """ import rudderstack.analytics as rudder_analytics rudder_analytics.write_key = "2Re4kqwL61GDp7S8ewe6K5dbogG" rudder_analytics.dataPlaneUrl = "https://gptengineerezm.dataplane.rudderstack.com" rudder_analytics.track( user_id=learning.session, event="learning", properties=learning.to_dict(), # type: ignore ) def collect_learnings( prompt: Prompt, model: str, temperature: float, config: any, memory: DiskMemory, review: Review, ): """ Collect the learning data and send it to RudderStack for analysis. Parameters ---------- prompt : str The initial prompt or question that was provided to the model. model : str The name of the model used for generating the response. temperature : float The temperature setting used in the model's response generation. config : any Configuration parameters used for the learning session. memory : DiskMemory An instance of DiskMemory for storing and retrieving data. review : Review An instance of Review containing human feedback on the model's response. Notes ----- This function attempts to send the learning data to RudderStack. If the data size exceeds the maximum allowed size, it trims the data and retries sending it. """ learnings = extract_learning(prompt, model, temperature, config, memory, review) try: send_learning(learnings) except RuntimeError: # try to remove some parts of learning that might be too big # rudderstack max event size is 32kb max_size = 32 << 10 # 32KB in bytes current_size = len(learnings.to_json().encode("utf-8")) # get size in bytes overflow = current_size - max_size # Add some extra characters for the "[REMOVED...]" string and for safety margin remove_length = overflow + len(f"[REMOVED {overflow} CHARACTERS]") + 100 learnings.logs = ( learnings.logs[:-remove_length] + f"\n\n[REMOVED {remove_length} CHARACTERS]" ) print( "WARNING: learning too big, removing some parts. " "Please report if this results in a crash." ) try: send_learning(learnings) except RuntimeError: print( "Sending learnings crashed despite truncation. Progressing without saving learnings." ) # def steps_file_hash(): # """ # Compute the SHA-256 hash of the steps file. # # Returns # ------- # str # The SHA-256 hash of the steps file. # """ # with open(steps.__file__, "r") as f: # content = f.read() # return hashlib.sha256(content.encode("utf-8")).hexdigest() def collect_and_send_human_review( prompt: Prompt, model: str, temperature: float, config: Tuple[str, ...], memory: DiskMemory, ): """ Collects human feedback on the code and sends it for analysis. Parameters ---------- prompt : str The initial prompt or question that was provided to the model. model : str The name of the model used for generating the response. temperature : float The temperature setting used in the model's response generation. config : Tuple[str, ...] Configuration parameters used for the learning session. memory : DiskMemory An instance of DiskMemory for storing and retrieving data. Returns ------- None Notes ----- This function prompts the user for a review of the generated or improved code using the `human_review_input` function. If a valid review is provided, it's serialized to JSON format and stored within the database's memory under the "review" key. """ review = human_review_input() if review: collect_learnings(prompt, model, temperature, config, memory, review) ================================================ FILE: gpt_engineer/applications/cli/file_selector.py ================================================ """ file_selector.py This module offers interactive file selection for projects. Leveraging a terminal-based, tree-structured display, users can navigate and select files for editing or processing. It integrates with system editors for direct file modification and supports saving selections for later use. Designed for efficient workflow enhancement in file-intensive environments, it offers customizable file filtering and seamless editor integration. Key Components: - FileSelector: Manages file selection and interaction. - DisplayablePath: Provides a structured view of file paths. Usage: Typically used in project setup or management phases for selecting specific files. It operates within the GPT-Engineer environment, relying on core functionalities for file handling and persistence. """ import fnmatch import os import subprocess from pathlib import Path from typing import Any, Dict, Generator, List, Union import toml from gpt_engineer.core.default.disk_memory import DiskMemory from gpt_engineer.core.default.paths import metadata_path from gpt_engineer.core.files_dict import FilesDict from gpt_engineer.core.git import filter_by_gitignore, is_git_repo class FileSelector: """ Manages file selection and interaction within a project directory. This class provides methods to interactively select files from the terminal, save selections for later use, and integrate with system editors for direct file modification. Attributes ---------- IGNORE_FOLDERS : set A set of directory names to ignore during file selection. FILE_LIST_NAME : str The name of the file that stores the selected files list. COMMENT : str The comment string to be added to the top of the file selection list. """ IGNORE_FOLDERS = {"site-packages", "node_modules", "venv", "__pycache__"} FILE_LIST_NAME = "file_selection.toml" COMMENT = ( "# Remove '#' to select a file or turn off linting.\n\n" "# Linting with BLACK (Python) enhances code suggestions from LLMs. " "To disable linting, uncomment the relevant option in the linting settings.\n\n" "# gpt-engineer can only read selected files. " "Including irrelevant files will degrade performance, " "cost additional tokens and potentially overflow token limit.\n\n" ) LINTING_STRING = '[linting]\n# "linting" = "off"\n\n' is_linting = True def __init__(self, project_path: Union[str, Path]): """ Initializes the FileSelector with a given project path. Parameters ---------- project_path : Union[str, Path] The path to the project directory where file selection is to be performed. """ self.project_path = project_path self.metadata_db = DiskMemory(metadata_path(self.project_path)) self.toml_path = self.metadata_db.path / self.FILE_LIST_NAME def ask_for_files(self, skip_file_selection=False) -> tuple[FilesDict, bool]: """ Prompts the user to select files for context improvement. This method supports selection from the terminal or using a previously saved list. In test mode, it retrieves files from a predefined TOML configuration. Returns ------- FilesDict A dictionary with file paths as keys and file contents as values. """ if os.getenv("GPTE_TEST_MODE") or skip_file_selection: # In test mode, retrieve files from a predefined TOML configuration # also get from toml if skip_file_selector is active assert self.FILE_LIST_NAME in self.metadata_db selected_files = self.get_files_from_toml(self.project_path, self.toml_path) else: # Otherwise, use the editor file selector for interactive selection if self.FILE_LIST_NAME in self.metadata_db: print( f"File list detected at {self.toml_path}. Edit or delete it if you want to select new files." ) selected_files = self.editor_file_selector(self.project_path, False) else: selected_files = self.editor_file_selector(self.project_path, True) content_dict = {} for file_path in selected_files: # selected files contains paths that are relative to the project path try: # to open the file we need the path from the cwd with open( Path(self.project_path) / file_path, "r", encoding="utf-8" ) as content: content_dict[str(file_path)] = content.read() except FileNotFoundError: print(f"Warning: File not found {file_path}") except UnicodeDecodeError: print(f"Warning: File not UTF-8 encoded {file_path}, skipping") return FilesDict(content_dict), self.is_linting def editor_file_selector( self, input_path: Union[str, Path], init: bool = True ) -> List[str]: """ Provides an interactive file selection interface using a .toml file. Parameters ---------- input_path : Union[str, Path] The path where file selection is to be performed. init : bool, optional Indicates whether to initialize the .toml file with the file tree. Returns ------- List[str] A list of strings representing the paths of selected files. """ root_path = Path(input_path) tree_dict = {} toml_file = DiskMemory(metadata_path(input_path)).path / "file_selection.toml" # Define the toml file path # Initialize .toml file with file tree if in initial state if init: tree_dict = {x: "selected" for x in self.get_current_files(root_path)} s = toml.dumps({"files": tree_dict}) # add comments on all lines that match = "selected" s = "\n".join( [ "# " + line if line.endswith(' = "selected"') else line for line in s.split("\n") ] ) # Write to the toml file with open(toml_file, "w") as f: f.write(self.COMMENT) f.write(self.LINTING_STRING) f.write(s) else: # Load existing files from the .toml configuration all_files = self.get_current_files(root_path) s = toml.dumps({"files": {x: "selected" for x in all_files}}) # get linting status from the toml file with open(toml_file, "r") as file: linting_status = toml.load(file) if ( "linting" in linting_status and linting_status["linting"].get("linting", "").lower() == "off" ): self.is_linting = False self.LINTING_STRING = '[linting]\n"linting" = "off"\n\n' print("\nLinting is disabled") with open(toml_file, "r") as file: selected_files = toml.load(file) lines = s.split("\n") s = "\n".join( lines[:1] + [ line if line.split(" = ")[0].strip('"') in selected_files["files"] else "# " + line for line in lines[1:] ] ) # Write the merged list back to the .toml for user review and modification with open(toml_file, "w") as file: file.write(self.COMMENT) # Ensure to write the comment file.write(self.LINTING_STRING) file.write(s) print( "Please select and deselect (add # in front) files, save it, and close it to continue..." ) self.open_with_default_editor( toml_file ) # Open the .toml file in the default editor for user modification return self.get_files_from_toml( input_path, toml_file ) # Return the list of selected files after user edits def open_with_default_editor(self, file_path: Union[str, Path]): """ Opens a file with the system's default text editor. Parameters ---------- file_path : Union[str, Path] The path to the file to be opened in the text editor. """ editors = [ "gedit", "notepad", "nvim", "write", "nano", "vim", "emacs", ] # Putting the beginner-friendly text editor forward chosen_editor = os.environ.get("EDITOR") # Try the preferred editor first, then fallback to common editors if chosen_editor: try: subprocess.run([chosen_editor, file_path]) return except Exception: pass for editor in editors: try: subprocess.run([editor, file_path]) return except Exception: continue print("No suitable text editor found. Please edit the file manually.") def is_utf8(self, file_path: Union[str, Path]) -> bool: """ Checks if the file at the given path is UTF-8 encoded. Parameters ---------- file_path : Union[str, Path] The path to the file to be checked. Returns ------- bool True if the file is UTF-8 encoded, False otherwise. """ try: with open(file_path, "rb") as file: file.read().decode("utf-8") return True except UnicodeDecodeError: return False def get_files_from_toml( self, input_path: Union[str, Path], toml_file: Union[str, Path] ) -> List[str]: """ Retrieves a list of selected files from a .toml configuration file. Parameters ---------- input_path : Union[str, Path] The path where file selection was performed. toml_file : Union[str, Path] The path to the .toml file containing the file selection. Returns ------- List[str] A list of strings representing the paths of selected files. Raises ------ Exception If no files are selected in the .toml file. """ selected_files = [] edited_tree = toml.load(toml_file) # Load the edited .toml file # check if users have disabled linting or not if ( "linting" in edited_tree and edited_tree["linting"].get("linting", "").lower() == "off" ): self.is_linting = False print("\nLinting is disabled") else: self.is_linting = True # Iterate through the files in the .toml and append selected files to the list for file, _ in edited_tree["files"].items(): selected_files.append(file) # Ensure that at least one file is selected, or raise an exception if not selected_files: raise Exception( "No files were selected. Please select at least one file to proceed." ) print(f"\nYou have selected the following files:\n{input_path}") project_path = Path(input_path).resolve() selected_paths = set( project_path.joinpath(file).resolve(strict=False) for file in selected_files ) for displayable_path in DisplayablePath.make_tree(project_path): if displayable_path.path in selected_paths: p = displayable_path while p.parent and p.parent.path not in selected_paths: selected_paths.add(p.parent.path) p = p.parent try: for displayable_path in DisplayablePath.make_tree(project_path): if displayable_path.path in selected_paths: print(displayable_path.displayable()) except FileNotFoundError: print("Specified path does not exist: ", project_path) except Exception as e: print("An error occurred while trying to display the file tree:", e) print("\n") return selected_files def merge_file_lists( self, existing_files: Dict[str, Any], new_files: Dict[str, Any] ) -> Dict[str, Any]: """ Merges two lists of files, preserving the selection status. Parameters ---------- existing_files : Dict[str, Any] The dictionary of existing files with their properties. new_files : Dict[str, Any] The dictionary of new files with their properties. Returns ------- Dict[str, Any] The updated dictionary of files after merging. """ # Update the existing files with any new files or changes for file, properties in new_files.items(): if file not in existing_files: existing_files[file] = properties # Add new files as unselected # If you want to update other properties of existing files, you can do so here return existing_files def should_filter_file(self, file_path: Path, filters: List[str]) -> bool: """ Determines if a file should be ignored based on .gitignore rules. """ for f in filters: if fnmatch.fnmatchcase(str(file_path), f): return True return False def get_current_files(self, project_path: Union[str, Path]) -> List[str]: """ Generates a list of all files in the project directory. Will use .gitignore files if project_path is a git repository. Parameters ---------- project_path : Union[str, Path] The path to the project directory. Returns ------- List[str] A list of strings representing the relative paths of all files in the project directory. """ all_files = [] project_path = Path( project_path ).resolve() # Ensure path is absolute and resolved file_list = project_path.glob("**/*") for path in file_list: # Recursively list all files if path.is_file(): relpath = path.relative_to(project_path) parts = relpath.parts if any(part.startswith(".") for part in parts): continue # Skip hidden files if any(part in self.IGNORE_FOLDERS for part in parts): continue if relpath.name == "prompt": continue # Skip files named 'prompt' all_files.append(str(relpath)) if is_git_repo(project_path) and "projects" not in project_path.parts: all_files = filter_by_gitignore(project_path, all_files) return sorted(all_files, key=lambda x: Path(x).as_posix()) class DisplayablePath(object): """ Represents and displays a file system path in a tree-like structure. This class is used to visually represent the structure of directories and files in a way that is similar to a file explorer's tree view. """ display_filename_prefix_middle = "├── " display_filename_prefix_last = "└── " display_parent_prefix_middle = " " display_parent_prefix_last = "│ " def __init__( self, path: Union[str, Path], parent_path: "DisplayablePath", is_last: bool ): """ Initializes a DisplayablePath object with a given path and parent. Parameters ---------- path : Union[str, Path] The file system path to be displayed. parent_path : DisplayablePath The parent path in the tree structure. is_last : bool Indicates whether this is the last sibling in the tree structure. """ self.depth = 0 self.path = Path(str(path)) self.parent = parent_path self.is_last = is_last if self.parent: self.depth = self.parent.depth + 1 # Increment depth if it has a parent @property def display_name(self) -> str: """ Get the display name of the file or directory. """ if self.path.is_dir(): return self.path.name + "/" return self.path.name @classmethod def make_tree( cls, root: Union[str, Path], parent=None, is_last=False, criteria=None ) -> Generator["DisplayablePath", None, None]: """ Creates a tree of DisplayablePath objects from a root directory. Parameters ---------- root : Union[str, Path] The root directory from which to start creating the tree. parent : DisplayablePath, optional The parent path in the tree structure. is_last : bool, optional Indicates whether this is the last sibling in the tree structure. criteria : callable, optional A function to filter the paths included in the tree. Yields ------ DisplayablePath The next DisplayablePath object in the tree. """ root = Path(str(root)) # Ensure root is a Path object criteria = criteria or cls._default_criteria displayable_root = cls(root, parent, is_last) yield displayable_root if root.is_dir(): # Check if root is a directory before iterating children = sorted( list(path for path in root.iterdir() if criteria(path)), key=lambda s: str(s).lower(), ) count = 1 for path in children: is_last = count == len(children) yield from cls.make_tree( path, parent=displayable_root, is_last=is_last, criteria=criteria ) count += 1 @classmethod def _default_criteria(cls, path: Path) -> bool: """ The default criteria function to filter the paths. """ return True def displayable(self) -> str: """ Returns a string representation of the path for display in a tree-like structure. Returns ------- str The displayable string representation of the file or directory. """ if self.parent is None: return self.display_name _filename_prefix = ( self.display_filename_prefix_last if self.is_last else self.display_filename_prefix_middle ) parts = ["{!s} {!s}".format(_filename_prefix, self.display_name)] parent = self.parent while parent and parent.parent is not None: parts.append( self.display_parent_prefix_middle if parent.is_last else self.display_parent_prefix_last ) parent = parent.parent return "".join(reversed(parts)) # Assemble the parts into the final string ================================================ FILE: gpt_engineer/applications/cli/learning.py ================================================ """ The `learning` module is designed to facilitate the collection and storage of user feedback on the outputs generated by the GPT Engineer tool. It provides mechanisms for obtaining user consent, capturing user reviews, and storing this information for future analysis and enhancement of the tool's performance. Classes ------- Review : dataclass Represents a user's review of the generated code, including whether it ran, was perfect, was useful, and any additional comments. Learning : dataclass Encapsulates the metadata and feedback collected during a session of using the GPT Engineer tool, including the prompt, model, temperature, configuration, logs, session identifier, user review, and timestamp. Functions --------- human_review_input() -> Optional[Review] Interactively gathers feedback from the user regarding the performance of generated code and returns a Review instance. check_collection_consent() -> bool Checks if the user has previously given consent to store their data and, if not, asks for it. ask_collection_consent() -> bool Prompts the user for consent to store their data for the purpose of improving GPT Engineer. extract_learning(prompt: Prompt, model: str, temperature: float, config: Tuple[str, ...], memory: DiskMemory, review: Review) -> Learning Extracts feedback and session details to create a Learning instance based on the provided parameters. get_session() -> str Retrieves a unique identifier for the current user session, creating one if it does not exist. Constants --------- TERM_CHOICES : tuple Terminal color choices for user interactive prompts, formatted with termcolor for readability. """ import json import random import tempfile from dataclasses import dataclass, field from datetime import datetime from pathlib import Path from typing import Optional, Tuple from dataclasses_json import dataclass_json from termcolor import colored from gpt_engineer.core.default.disk_memory import DiskMemory from gpt_engineer.core.prompt import Prompt @dataclass_json @dataclass class Review: """ A dataclass that represents a user's review of the generated code. Attributes ---------- ran : Optional[bool] Indicates whether the generated code ran without errors. perfect : Optional[bool] Indicates whether the generated code met all the user's requirements. works : Optional[bool] Indicates whether the generated code was useful, even if not perfect. comments : str Any additional comments provided by the user. raw : str A raw string representation of the user's responses. """ ran: Optional[bool] perfect: Optional[bool] works: Optional[bool] comments: str raw: str @dataclass_json @dataclass class Learning: """ A dataclass that encapsulates the learning data collected during a GPT Engineer session. Attributes ---------- prompt : str A JSON string representing the prompt provided to GPT Engineer. model : str The name of the model used during the session. temperature : float The temperature setting used for the model's responses. config : str A JSON string representing the configuration settings for the session. logs : str A JSON string representing the logs of the session. session : str A unique identifier for the user session. review : Optional[Review] The user's review of the generated code. timestamp : str The UTC timestamp when the learning data was created. version : str The version of the learning data schema. """ prompt: str model: str temperature: float config: str logs: str session: str review: Optional[Review] timestamp: str = field(default_factory=lambda: datetime.utcnow().isoformat()) version: str = "0.3" TERM_CHOICES = ( colored("y", "green") + "/" + colored("n", "red") + "/" + colored("u", "yellow") + "(ncertain): " ) def human_review_input() -> Optional[Review]: """ Interactively prompts the user to review the generated code and returns their feedback encapsulated in a Review object. This function will first check if the user has given consent to collect their feedback. If consent is given, it will ask the user a series of questions about the generated code's performance and capture their responses. Returns ------- Optional[Review] A Review object containing the user's feedback, or None if consent is not given. """ print() if not check_collection_consent(): return None print() print( colored("To help gpt-engineer learn, please answer 3 questions:", "light_green") ) print() ran = input("Did the generated code run at all? " + TERM_CHOICES) ran = ask_for_valid_input(ran) if ran == "y": perfect = input( "Did the generated code do everything you wanted? " + TERM_CHOICES ) perfect = ask_for_valid_input(perfect) if perfect != "y": useful = input("Did the generated code do anything useful? " + TERM_CHOICES) useful = ask_for_valid_input(useful) else: useful = "" else: perfect = "" useful = "" if perfect != "y": comments = input( "If you have time, please explain what was not working " + colored("(ok to leave blank)\n", "light_green") ) else: comments = "" return Review( raw=", ".join([ran, perfect, useful]), ran={"y": True, "n": False, "u": None, "": None}[ran], works={"y": True, "n": False, "u": None, "": None}[useful], perfect={"y": True, "n": False, "u": None, "": None}[perfect], comments=comments, ) def ask_for_valid_input(ran): while ran not in ("y", "n", "u"): ran = input("Invalid input. Please enter y, n, or u: ") return ran def check_collection_consent() -> bool: """ Checks if the user has previously given consent to store their data for feedback collection. This function looks for a file that stores the user's consent status. If the file exists and contains 'true', consent is assumed. If the file does not exist or does not contain 'true', the function will prompt the user for consent. Returns ------- bool True if the user has given consent, False otherwise. """ path = Path(".gpte_consent") if path.exists() and path.read_text() == "true": return True else: return ask_collection_consent() def ask_collection_consent() -> bool: """ Asks the user for their consent to store their data for the purpose of improving the GPT Engineer tool. The user's response is recorded in a file for future reference. If the user consents, the function will write 'true' to the file. If the user does not consent, no data will be collected, and the function will not modify the file. Returns ------- bool True if the user consents, False otherwise. """ answer = input( "Is it ok if we store your prompts to help improve GPT Engineer? (y/n)" ) while answer.lower() not in ("y", "n"): answer = input("Invalid input. Please enter y or n: ") if answer.lower() == "y": path = Path(".gpte_consent") path.write_text("true") print(colored("Thank you️", "light_green")) print() print( "(If you no longer wish to participate in data collection, delete the file .gpte_consent)" ) return True else: print( colored( "No worries! GPT Engineer will not collect your prompts. ❤️", "light_green", ) ) return False def extract_learning( prompt: Prompt, model: str, temperature: float, config: Tuple[str, ...], memory: DiskMemory, review: Review, ) -> Learning: """ Constructs a Learning object containing the session's metadata and user feedback. Parameters ---------- prompt : str The initial prompt provided to the GPT Engineer. model : str The name of the model used during the session. temperature : float The temperature setting used for the model's responses. config : Tuple[str, ...] A tuple representing the configuration settings for the session. memory : DiskMemory An object representing the disk memory used during the session. review : Review The user's review of the generated code. Returns ------- Learning An instance of Learning containing all the session details and user feedback. """ return Learning( prompt=prompt.to_json(), model=model, temperature=temperature, config=json.dumps(config), session=get_session(), logs=memory.to_json(), review=review, ) def get_session() -> str: """ Retrieves or generates a unique identifier for the current user session. This function attempts to read a unique user ID from a temporary file. If the file does not exist, it generates a new random ID, writes it to the file, and returns it. This ID is used to uniquely identify the user's session. Returns ------- str A unique identifier for the user session. """ path = Path(tempfile.gettempdir()) / "gpt_engineer_user_id.txt" try: if path.exists(): user_id = path.read_text() else: # random uuid: user_id = str(random.randint(0, 2**32)) path.write_text(user_id) return user_id except IOError: return "ephemeral_" + str(random.randint(0, 2**32)) ================================================ FILE: gpt_engineer/applications/cli/main.py ================================================ """ Entrypoint for the CLI tool. This module serves as the entry point for a command-line interface (CLI) tool. It is designed to interact with OpenAI's language models. The module provides functionality to: - Load necessary environment variables, - Configure various parameters for the AI interaction, - Manage the generation or improvement of code projects. Main Functionality ------------------ - Load environment variables required for OpenAI API interaction. - Parse user-specified parameters for project configuration and AI behavior. - Facilitate interaction with AI models, databases, and archival processes. Parameters ---------- None Notes ----- - The `OPENAI_API_KEY` must be set in the environment or provided in a `.env` file within the working directory. - The default project path is `projects/example`. - When using the `azure_endpoint` parameter, provide the Azure OpenAI service endpoint URL. """ import difflib import json import logging import os import platform import subprocess import sys from pathlib import Path import openai import typer from dotenv import load_dotenv from langchain.globals import set_llm_cache from langchain_community.cache import SQLiteCache from termcolor import colored from gpt_engineer.applications.cli.cli_agent import CliAgent from gpt_engineer.applications.cli.collect import collect_and_send_human_review from gpt_engineer.applications.cli.file_selector import FileSelector from gpt_engineer.core.ai import AI, ClipboardAI from gpt_engineer.core.default.disk_execution_env import DiskExecutionEnv from gpt_engineer.core.default.disk_memory import DiskMemory from gpt_engineer.core.default.file_store import FileStore from gpt_engineer.core.default.paths import PREPROMPTS_PATH, memory_path from gpt_engineer.core.default.steps import ( execute_entrypoint, gen_code, handle_improve_mode, improve_fn as improve_fn, ) from gpt_engineer.core.files_dict import FilesDict from gpt_engineer.core.git import stage_uncommitted_to_git from gpt_engineer.core.preprompts_holder import PrepromptsHolder from gpt_engineer.core.prompt import Prompt from gpt_engineer.tools.custom_steps import clarified_gen, lite_gen, self_heal app = typer.Typer( context_settings={"help_option_names": ["-h", "--help"]} ) # creates a CLI app def load_env_if_needed(): """ Load environment variables if the OPENAI_API_KEY is not already set. This function checks if the OPENAI_API_KEY environment variable is set, and if not, it attempts to load it from a .env file in the current working directory. It then sets the openai.api_key for use in the application. """ # We have all these checks for legacy reasons... if os.getenv("OPENAI_API_KEY") is None: load_dotenv() if os.getenv("OPENAI_API_KEY") is None: load_dotenv(dotenv_path=os.path.join(os.getcwd(), ".env")) openai.api_key = os.getenv("OPENAI_API_KEY") if os.getenv("ANTHROPIC_API_KEY") is None: load_dotenv() if os.getenv("ANTHROPIC_API_KEY") is None: load_dotenv(dotenv_path=os.path.join(os.getcwd(), ".env")) def concatenate_paths(base_path, sub_path): # Compute the relative path from base_path to sub_path relative_path = os.path.relpath(sub_path, base_path) # If the relative path is not in the parent directory, use the original sub_path if not relative_path.startswith(".."): return sub_path # Otherwise, concatenate base_path and sub_path return os.path.normpath(os.path.join(base_path, sub_path)) def load_prompt( input_repo: DiskMemory, improve_mode: bool, prompt_file: str, image_directory: str, entrypoint_prompt_file: str = "", ) -> Prompt: """ Load or request a prompt from the user based on the mode. Parameters ---------- input_repo : DiskMemory The disk memory object where prompts and other data are stored. improve_mode : bool Flag indicating whether the application is in improve mode. Returns ------- str The loaded or inputted prompt. """ if os.path.isdir(prompt_file): raise ValueError( f"The path to the prompt, {prompt_file}, already exists as a directory. No prompt can be read from it. Please specify a prompt file using --prompt_file" ) prompt_str = input_repo.get(prompt_file) if prompt_str: print(colored("Using prompt from file:", "green"), prompt_file) print(prompt_str) else: if not improve_mode: prompt_str = input( "\nWhat application do you want gpt-engineer to generate?\n" ) else: prompt_str = input("\nHow do you want to improve the application?\n") if entrypoint_prompt_file == "": entrypoint_prompt = "" else: full_entrypoint_prompt_file = concatenate_paths( input_repo.path, entrypoint_prompt_file ) if os.path.isfile(full_entrypoint_prompt_file): entrypoint_prompt = input_repo.get(full_entrypoint_prompt_file) else: raise ValueError("The provided file at --entrypoint-prompt does not exist") if image_directory == "": return Prompt(prompt_str, entrypoint_prompt=entrypoint_prompt) full_image_directory = concatenate_paths(input_repo.path, image_directory) if os.path.isdir(full_image_directory): if len(os.listdir(full_image_directory)) == 0: raise ValueError("The provided --image_directory is empty.") image_repo = DiskMemory(full_image_directory) return Prompt( prompt_str, image_repo.get(".").to_dict(), entrypoint_prompt=entrypoint_prompt, ) else: raise ValueError("The provided --image_directory is not a directory.") def get_preprompts_path(use_custom_preprompts: bool, input_path: Path) -> Path: """ Get the path to the preprompts, using custom ones if specified. Parameters ---------- use_custom_preprompts : bool Flag indicating whether to use custom preprompts. input_path : Path The path to the project directory. Returns ------- Path The path to the directory containing the preprompts. """ original_preprompts_path = PREPROMPTS_PATH if not use_custom_preprompts: return original_preprompts_path custom_preprompts_path = input_path / "preprompts" if not custom_preprompts_path.exists(): custom_preprompts_path.mkdir() for file in original_preprompts_path.glob("*"): if not (custom_preprompts_path / file.name).exists(): (custom_preprompts_path / file.name).write_text(file.read_text()) return custom_preprompts_path def compare(f1: FilesDict, f2: FilesDict): def colored_diff(s1, s2): lines1 = s1.splitlines() lines2 = s2.splitlines() diff = difflib.unified_diff(lines1, lines2, lineterm="") RED = "\033[38;5;202m" GREEN = "\033[92m" RESET = "\033[0m" colored_lines = [] for line in diff: if line.startswith("+"): colored_lines.append(GREEN + line + RESET) elif line.startswith("-"): colored_lines.append(RED + line + RESET) else: colored_lines.append(line) return "\n".join(colored_lines) for file in sorted(set(f1) | set(f2)): diff = colored_diff(f1.get(file, ""), f2.get(file, "")) if diff: print(f"Changes to {file}:") print(diff) def prompt_yesno() -> bool: TERM_CHOICES = colored("y", "green") + "/" + colored("n", "red") + " " while True: response = input(TERM_CHOICES).strip().lower() if response in ["y", "yes"]: return True if response in ["n", "no"]: break print("Please respond with 'y' or 'n'") def get_system_info(): system_info = { "os": platform.system(), "os_version": platform.version(), "architecture": platform.machine(), "python_version": sys.version, "packages": format_installed_packages(get_installed_packages()), } return system_info def get_installed_packages(): try: result = subprocess.run( [sys.executable, "-m", "pip", "list", "--format=json"], capture_output=True, text=True, ) packages = json.loads(result.stdout) return {pkg["name"]: pkg["version"] for pkg in packages} except Exception as e: return str(e) def format_installed_packages(packages): return "\n".join([f"{name}: {version}" for name, version in packages.items()]) @app.command( help=""" GPT-engineer lets you: \b - Specify a software in natural language - Sit back and watch as an AI writes and executes the code - Ask the AI to implement improvements """ ) def main( project_path: str = typer.Argument(".", help="path"), model: str = typer.Option( os.environ.get("MODEL_NAME", "gpt-4o"), "--model", "-m", help="model id string" ), temperature: float = typer.Option( 0.1, "--temperature", "-t", help="Controls randomness: lower values for more focused, deterministic outputs", ), improve_mode: bool = typer.Option( False, "--improve", "-i", help="Improve an existing project by modifying the files.", ), lite_mode: bool = typer.Option( False, "--lite", "-l", help="Lite mode: run a generation using only the main prompt.", ), clarify_mode: bool = typer.Option( False, "--clarify", "-c", help="Clarify mode - discuss specification with AI before implementation.", ), self_heal_mode: bool = typer.Option( False, "--self-heal", "-sh", help="Self-heal mode - fix the code by itself when it fails.", ), azure_endpoint: str = typer.Option( "", "--azure", "-a", help="""Endpoint for your Azure OpenAI Service (https://xx.openai.azure.com). In that case, the given model is the deployment name chosen in the Azure AI Studio.""", ), use_custom_preprompts: bool = typer.Option( False, "--use-custom-preprompts", help="""Use your project's custom preprompts instead of the default ones. Copies all original preprompts to the project's workspace if they don't exist there.""", ), llm_via_clipboard: bool = typer.Option( False, "--llm-via-clipboard", help="Use the clipboard to communicate with the AI.", ), verbose: bool = typer.Option( False, "--verbose", "-v", help="Enable verbose logging for debugging." ), debug: bool = typer.Option( False, "--debug", "-d", help="Enable debug mode for debugging." ), prompt_file: str = typer.Option( "prompt", "--prompt_file", help="Relative path to a text file containing a prompt.", ), entrypoint_prompt_file: str = typer.Option( "", "--entrypoint_prompt", help="Relative path to a text file containing a file that specifies requirements for you entrypoint.", ), image_directory: str = typer.Option( "", "--image_directory", help="Relative path to a folder containing images.", ), use_cache: bool = typer.Option( False, "--use_cache", help="Speeds up computations and saves tokens when running the same prompt multiple times by caching the LLM response.", ), skip_file_selection: bool = typer.Option( False, "--skip-file-selection", "-s", help="Skip interactive file selection in improve mode and use the generated TOML file directly.", ), no_execution: bool = typer.Option( False, "--no_execution", help="Run setup but to not call LLM or write any code. For testing purposes.", ), sysinfo: bool = typer.Option( False, "--sysinfo", help="Output system information for debugging", ), diff_timeout: int = typer.Option( 3, "--diff_timeout", help="Diff regexp timeout. Default: 3. Increase if regexp search timeouts.", ), ): """ The main entry point for the CLI tool that generates or improves a project. This function sets up the CLI tool, loads environment variables, initializes the AI, and processes the user's request to generate or improve a project based on the provided arguments. Parameters ---------- project_path : str The file path to the project directory. model : str The model ID string for the AI. temperature : float The temperature setting for the AI's responses. improve_mode : bool Flag indicating whether to improve an existing project. lite_mode : bool Flag indicating whether to run in lite mode. clarify_mode : bool Flag indicating whether to discuss specifications with AI before implementation. self_heal_mode : bool Flag indicating whether to enable self-healing mode. azure_endpoint : str The endpoint for Azure OpenAI services. use_custom_preprompts : bool Flag indicating whether to use custom preprompts. prompt_file : str Relative path to a text file containing a prompt. entrypoint_prompt_file: str Relative path to a text file containing a file that specifies requirements for you entrypoint. image_directory: str Relative path to a folder containing images. use_cache: bool Speeds up computations and saves tokens when running the same prompt multiple times by caching the LLM response. verbose : bool Flag indicating whether to enable verbose logging. skip_file_selection: bool Skip interactive file selection in improve mode and use the generated TOML file directly no_execution: bool Run setup but to not call LLM or write any code. For testing purposes. sysinfo: bool Flag indicating whether to output system information for debugging. Returns ------- None """ if debug: import pdb sys.excepthook = lambda *_: pdb.pm() if sysinfo: sys_info = get_system_info() for key, value in sys_info.items(): print(f"{key}: {value}") raise typer.Exit() # Validate arguments if improve_mode and (clarify_mode or lite_mode): typer.echo("Error: Clarify and lite mode are not compatible with improve mode.") raise typer.Exit(code=1) # Set up logging logging.basicConfig(level=logging.DEBUG if verbose else logging.INFO) if use_cache: set_llm_cache(SQLiteCache(database_path=".langchain.db")) if improve_mode: assert not ( clarify_mode or lite_mode ), "Clarify and lite mode are not active for improve mode" load_env_if_needed() if llm_via_clipboard: ai = ClipboardAI() else: ai = AI( model_name=model, temperature=temperature, azure_endpoint=azure_endpoint, ) path = Path(project_path) print("Running gpt-engineer in", path.absolute(), "\n") prompt = load_prompt( DiskMemory(path), improve_mode, prompt_file, image_directory, entrypoint_prompt_file, ) # todo: if ai.vision is false and not llm_via_clipboard - ask if they would like to use gpt-4-vision-preview instead? If so recreate AI if not ai.vision: prompt.image_urls = None # configure generation function if clarify_mode: code_gen_fn = clarified_gen elif lite_mode: code_gen_fn = lite_gen else: code_gen_fn = gen_code # configure execution function if self_heal_mode: execution_fn = self_heal else: execution_fn = execute_entrypoint preprompts_holder = PrepromptsHolder( get_preprompts_path(use_custom_preprompts, Path(project_path)) ) memory = DiskMemory(memory_path(project_path)) memory.archive_logs() execution_env = DiskExecutionEnv() agent = CliAgent.with_default_config( memory, execution_env, ai=ai, code_gen_fn=code_gen_fn, improve_fn=improve_fn, process_code_fn=execution_fn, preprompts_holder=preprompts_holder, ) files = FileStore(project_path) if not no_execution: if improve_mode: files_dict_before, is_linting = FileSelector(project_path).ask_for_files( skip_file_selection=skip_file_selection ) # lint the code if is_linting: files_dict_before = files.linting(files_dict_before) files_dict = handle_improve_mode( prompt, agent, memory, files_dict_before, diff_timeout=diff_timeout ) if not files_dict or files_dict_before == files_dict: print( f"No changes applied. Could you please upload the debug_log_file.txt in {memory.path}/logs folder in a github issue?" ) else: print("\nChanges to be made:") compare(files_dict_before, files_dict) print() print(colored("Do you want to apply these changes?", "light_green")) if not prompt_yesno(): files_dict = files_dict_before else: files_dict = agent.init(prompt) # collect user feedback if user consents config = (code_gen_fn.__name__, execution_fn.__name__) collect_and_send_human_review(prompt, model, temperature, config, memory) stage_uncommitted_to_git(path, files_dict, improve_mode) files.push(files_dict) if ai.token_usage_log.is_openai_model(): print("Total api cost: $ ", ai.token_usage_log.usage_cost()) elif os.getenv("LOCAL_MODEL"): print("Total api cost: $ 0.0 since we are using local LLM.") else: print("Total tokens used: ", ai.token_usage_log.total_tokens()) if __name__ == "__main__": app() ================================================ FILE: gpt_engineer/benchmark/__init__.py ================================================ ================================================ FILE: gpt_engineer/benchmark/__main__.py ================================================ """ Main entry point for the benchmarking tool. This module provides a command-line interface for running benchmarks using Typer. It allows users to specify the path to an agent, the benchmark(s) to run, and other options such as verbosity. Functions --------- get_agent : function Dynamically imports and returns the default configuration agent from the given path. main : function The main function that runs the specified benchmarks with the given agent. Outputs the results to the console. Attributes ---------- __name__ : str The standard boilerplate for invoking the main function when the script is executed. """ import importlib import os.path import sys from typing import Annotated, Optional import typer from langchain.globals import set_llm_cache from langchain_community.cache import SQLiteCache from gpt_engineer.applications.cli.main import load_env_if_needed from gpt_engineer.benchmark.bench_config import BenchConfig from gpt_engineer.benchmark.benchmarks.load import get_benchmark from gpt_engineer.benchmark.run import export_yaml_results, print_results, run app = typer.Typer( context_settings={"help_option_names": ["-h", "--help"]} ) # creates a CLI app def get_agent(path): """ Dynamically imports and returns the default configuration agent from the given path. Parameters ---------- path : str The file path to the module containing the default configuration agent. Returns ------- BaseAgent An instance of the imported default configuration agent. """ # Dynamically import the python module at path sys.path.append(os.path.dirname(path)) agent_module = importlib.import_module(path.replace("/", ".").replace(".py", "")) return agent_module.default_config_agent() @app.command( help=""" Run any benchmark(s) against the specified agent. \b Currently available benchmarks are: apps and mbpp """ ) def main( path_to_agent: Annotated[ str, typer.Argument( help="python file that contains a function called 'default_config_agent'" ), ], bench_config: Annotated[ str, typer.Argument(help="optional task name in benchmark") ] = os.path.join(os.path.dirname(__file__), "default_bench_config.toml"), yaml_output: Annotated[ Optional[str], typer.Option(help="print results for each task", show_default=False), ] = None, verbose: Annotated[ Optional[bool], typer.Option(help="print results for each task", show_default=False), ] = False, use_cache: Annotated[ Optional[bool], typer.Option( help="Speeds up computations and saves tokens when running the same prompt multiple times by caching the LLM response.", show_default=False, ), ] = True, ): """ The main function that runs the specified benchmarks with the given agent and outputs the results to the console. Parameters ---------- path_to_agent : str The file path to the Python module that contains a function called 'default_config_agent'. bench_config : str, default=default_bench_config.toml Configuration file for choosing which benchmark problems to run. See default config for more details. yaml_output: Optional[str], default=None Pass a path to a yaml file to have results written to file. verbose : Optional[bool], default=False A flag to indicate whether to print results for each task. use_cache : Optional[bool], default=True Speeds up computations and saves tokens when running the same prompt multiple times by caching the LLM response. Returns ------- None """ if use_cache: set_llm_cache(SQLiteCache(database_path=".langchain.db")) load_env_if_needed() config = BenchConfig.from_toml(bench_config) print("using config file: " + bench_config) benchmarks = list() benchmark_results = dict() for specific_config_name in vars(config): specific_config = getattr(config, specific_config_name) if hasattr(specific_config, "active"): if specific_config.active: benchmarks.append(specific_config_name) for benchmark_name in benchmarks: benchmark = get_benchmark(benchmark_name, config) if len(benchmark.tasks) == 0: print( benchmark_name + " was skipped, since no tasks are specified. Increase the number of tasks in the config file at: " + bench_config ) continue agent = get_agent(path_to_agent) results = run(agent, benchmark, verbose=verbose) print( f"\n--- Results for agent {path_to_agent}, benchmark: {benchmark_name} ---" ) print_results(results) print() benchmark_results[benchmark_name] = { "detailed": [result.to_dict() for result in results] } if yaml_output is not None: export_yaml_results(yaml_output, benchmark_results, config.to_dict()) if __name__ == "__main__": typer.run(main) ================================================ FILE: gpt_engineer/benchmark/bench_config.py ================================================ from dataclasses import dataclass, field from pathlib import Path from tomlkit.items import Integer from gpt_engineer.core.project_config import read_config @dataclass class AppsConfig: active: bool | None = True test_start_index: int | None = 0 test_end_index: int | None = 1 train_start_index: int | None = 0 train_end_index: int | None = 0 examples_per_problem: int | None = 10 @dataclass class MbppConfig: active: bool | None = True test_len: int | None = 1 train_len: int | None = 0 @dataclass class GptmeConfig: active: bool | None = True @dataclass class BenchConfig: """Configuration for the GPT Engineer CLI and gptengineer.app via `gpt-engineer.toml`.""" apps: AppsConfig = field(default_factory=AppsConfig) mbpp: MbppConfig = field(default_factory=MbppConfig) gptme: GptmeConfig = field(default_factory=GptmeConfig) @classmethod def from_toml(cls, config_file: Path | str): if isinstance(config_file, str): config_file = Path(config_file) config_dict = read_config(config_file) return cls.from_dict(config_dict) @classmethod def from_dict(cls, config_dict: dict): return cls( apps=AppsConfig(**config_dict.get("apps", {})), mbpp=MbppConfig(**config_dict.get("mbpp", {})), gptme=GptmeConfig(**config_dict.get("gptme", {})), ) @staticmethod def recursive_resolve(data_dict): for key, value in data_dict.items(): if isinstance(value, Integer): data_dict[key] = int(value) elif isinstance(value, dict): BenchConfig.recursive_resolve(value) def to_dict(self): dict_config = { benchmark_name: {key: val for key, val in spec_config.__dict__.items()} for benchmark_name, spec_config in self.__dict__.items() } BenchConfig.recursive_resolve(dict_config) return dict_config ================================================ FILE: gpt_engineer/benchmark/benchmarks/apps/load.py ================================================ """ Module for loading APPS evaluation tasks. This module provides functionality to load tasks for evaluating GPT-based models on smaller, more focused tasks. It defines a set of tasks with predefined prompts and assertions to benchmark the performance of AI models. Functions --------- load_apps : function Loads the APPS benchmark, which consists of a series coding problems. """ from pathlib import Path from subprocess import TimeoutExpired from typing import Union from datasets import Dataset, DatasetDict, load_dataset, load_from_disk from gpt_engineer.benchmark.bench_config import AppsConfig from gpt_engineer.benchmark.benchmarks.apps.problem import Problem from gpt_engineer.benchmark.types import Assertable, Benchmark, Task from gpt_engineer.core.default.disk_execution_env import DiskExecutionEnv from gpt_engineer.core.files_dict import FilesDict from gpt_engineer.core.prompt import Prompt DATASET_PATH = Path(__file__).parent / "dataset" class AppsAssertion: def __init__(self, expected: str, command: str): self.expected_output = self._format(expected) self.command = command def evaluate(self, assertable: Assertable) -> bool: # Create new execution environment for every run to avoid side effects env = DiskExecutionEnv() env.upload(assertable.files) pro = env.popen(self.command) try: stdout, stderr = pro.communicate(timeout=2) stdout, stderr = stdout.decode("utf-8"), stderr.decode("utf-8") except TimeoutExpired: print("Execution Timeout") return False return self.expected_output in self._format(stdout) def _format(self, string: str) -> str: return string.replace(" ", "").replace("\n", "") def _get_dataset() -> Union[Dataset, DatasetDict]: try: return load_from_disk(str(DATASET_PATH)) except FileNotFoundError: print("Dataset not found locally, downloading...") dataset = load_dataset("codeparrot/apps", trust_remote_code=True) dataset.save_to_disk(str(DATASET_PATH)) return dataset def load_apps(config: AppsConfig) -> Benchmark: """ Loads the APPS benchmark, which consists of a series coding problems. Returns ------- Benchmark A Benchmark object containing a list of Task objects for the APPS evaluation. """ dataset = _get_dataset() tasks = [] problems = list() for dataset_type in ["test", "train"]: problems += [ Problem( id=problem["problem_id"], question=problem["question"], input_output=problem["input_output"], starter_code=problem["starter_code"], ) for index, problem in enumerate(dataset[dataset_type]) if (index < config.__getattribute__(dataset_type + "_end_index")) and (index >= config.__getattribute__(dataset_type + "_start_index")) ] for problem in problems: prompt = Prompt( problem.question + "\nThe program, including its inputs, should be run from the command " "line like 'python main \"input1 input2 etc \"', with all inputs inside " "the quotation marks. The program should not read inputs from stdin." ) tasks.append( Task( name=str(problem.id), initial_code=FilesDict({"main.py": problem.starter_code}), command=None, # Explicitly setting `None` because each assertion specifies its command prompt=prompt, assertions={ f"correct output {i}": AppsAssertion( expected=problem.outputs[i], command="python main.py" + ' "' + problem.inputs[i] + '"', ).evaluate for i in range( min(len(problem.outputs), config.examples_per_problem) ) }, ) ) return Benchmark( name="apps", tasks=tasks, ) ================================================ FILE: gpt_engineer/benchmark/benchmarks/apps/problem.py ================================================ import json from dataclasses import dataclass from functools import cached_property from typing import List @dataclass(frozen=True) class Problem: id: int question: str input_output: str starter_code: str @property def inputs(self) -> List[str]: return self._parsed_inputs_outputs["inputs"] @property def outputs(self) -> List[str]: return self._parsed_inputs_outputs["outputs"] @cached_property def _parsed_inputs_outputs(self): return json.loads(self.input_output.replace("\n", "")) ================================================ FILE: gpt_engineer/benchmark/benchmarks/apps/problems.py ================================================ # TODO: Pick problems # Temporary testing against these problems PROBLEM_IDS = list(range(0, 50)) ================================================ FILE: gpt_engineer/benchmark/benchmarks/gptme/load.py ================================================ """ Module for loading GPT-Me evaluation tasks. This module provides functionality to load tasks for evaluating GPT-based models on smaller, more focused tasks. It defines a set of tasks with predefined prompts and assertions to benchmark the performance of AI models. Functions --------- load_gptme : function Loads the GPT-Me benchmark, which consists of a series of tasks for evaluation. """ from gpt_engineer.benchmark.bench_config import GptmeConfig from gpt_engineer.benchmark.types import Benchmark, Task from gpt_engineer.core.files_dict import FilesDict from gpt_engineer.core.prompt import Prompt def load_gptme(config: GptmeConfig) -> Benchmark: """ Loads the GPT-Me benchmark, which consists of a series of tasks for evaluation. Returns ------- Benchmark A Benchmark object containing a list of Task objects for the GPT-Me evaluation. """ return Benchmark( name="gptme", tasks=[ Task( name="hello", initial_code=FilesDict({"hello.py": "print('Hello, world!')"}), command="python hello.py", prompt=Prompt("Change the code in hello.py to print 'Hello, human!'"), assertions={ "correct output": lambda assertable: assertable.stdout == "Hello, human!\n", "correct file": lambda assertable: assertable.files[ "hello.py" ].strip() == "print('Hello, human!')", }, ), Task( name="hello-patch", initial_code=FilesDict({"hello.py": "print('Hello, world!')"}), command="python hello.py", prompt=Prompt("Patch the code in hello.py to print 'Hello, human!'"), assertions={ "correct output": lambda assertable: assertable.stdout == "Hello, human!\n", "correct file": lambda assertable: assertable.files[ "hello.py" ].strip() == "print('Hello, human!')", }, ), Task( name="hello-ask", initial_code=FilesDict({"hello.py": "print('Hello, world!')"}), command="echo 'Erik' | python hello.py", prompt=Prompt( "modify hello.py to ask the user for their name and print 'Hello, !'. don't try to execute it" ), assertions={ "correct output": lambda assertable: "Hello, Erik!" in assertable.stdout, }, ), Task( name="prime100", initial_code=FilesDict( {} ), # Empty dictionary since no initial code is provided command="python prime.py", prompt=Prompt( "write a script prime.py that computes and prints the 100th prime number" ), assertions={ "correct output": lambda assertable: "541" in assertable.stdout.split(), }, ), Task( name="init-git", initial_code=FilesDict( {} ), # Empty dictionary since no initial code is provided command="git status", prompt=Prompt( "initialize a git repository, write a main.py file, and commit it" ), assertions={ "clean exit": lambda assertable: assertable.process.returncode == 0, "clean working tree": lambda assertable: "nothing to commit, working tree clean" in assertable.stdout, "main.py exists": lambda assertable: "main.py" in assertable.files, "we have a commit": lambda assertable: "No commits yet" not in assertable.stdout, }, ), ], ) ================================================ FILE: gpt_engineer/benchmark/benchmarks/load.py ================================================ """ Module for loading benchmarks. This module provides a central point to access different benchmarks by name. It maps benchmark names to their respective loading functions. Functions --------- get_benchmark : function Retrieves a Benchmark object by name. Raises ValueError if the benchmark is unknown. """ from gpt_engineer.benchmark.bench_config import BenchConfig from gpt_engineer.benchmark.benchmarks.apps.load import load_apps from gpt_engineer.benchmark.benchmarks.gptme.load import load_gptme from gpt_engineer.benchmark.benchmarks.mbpp.load import load_mbpp from gpt_engineer.benchmark.types import Benchmark BENCHMARKS = { "gptme": load_gptme, "apps": load_apps, "mbpp": load_mbpp, } def get_benchmark(name: str, config: BenchConfig) -> Benchmark: """ Retrieves a Benchmark object by name. Raises ValueError if the benchmark is unknown. Parameters ---------- name : str The name of the benchmark to retrieve. config : BenchConfig Configuration object for the benchmarks. Returns ------- Benchmark The Benchmark object corresponding to the given name. Raises ------ ValueError If the benchmark name is not found in the BENCHMARKS mapping. """ if name not in BENCHMARKS: raise ValueError(f"Unknown benchmark {name}.") return BENCHMARKS[name](config.__getattribute__(name)) ================================================ FILE: gpt_engineer/benchmark/benchmarks/mbpp/load.py ================================================ """ Module for loading MBPP evaluation tasks. This module provides functionality to load tasks for evaluating GPT-based models on smaller, more focused tasks. It defines a set of tasks with predefined prompts and assertions to benchmark the performance of AI models. Functions --------- load_mbpp : function Loads the MBPP benchmark, which consists of a series coding problems. """ from pathlib import Path from subprocess import TimeoutExpired from typing import Union from datasets import Dataset, DatasetDict, load_dataset, load_from_disk from gpt_engineer.benchmark.bench_config import MbppConfig from gpt_engineer.benchmark.benchmarks.mbpp.problem import Problem from gpt_engineer.benchmark.types import Assertable, Benchmark, Task from gpt_engineer.core.default.disk_execution_env import DiskExecutionEnv from gpt_engineer.core.files_dict import FilesDict from gpt_engineer.core.prompt import Prompt DATASET_PATH = Path(__file__).parent / "dataset" class MbppAssertion: def __init__(self, assertion: str): self.assertion = assertion def evaluate(self, assertable: Assertable) -> bool: generated_code = assertable.files["main.py"] code_with_assertion = f"{generated_code}\n{self.assertion}" # Create new execution environment for every run to avoid side effects env = DiskExecutionEnv() env.upload(FilesDict({"main.py": code_with_assertion})) pro = env.popen("python main.py") try: stdout, stderr = pro.communicate(timeout=2) stdout, stderr = stdout.decode("utf-8"), stderr.decode("utf-8") except TimeoutExpired: print("Execution Timeout") return False return not stderr def _get_dataset() -> Union[Dataset, DatasetDict]: try: return load_from_disk(str(DATASET_PATH)) except FileNotFoundError: print("Dataset not found locally, downloading...") dataset = load_dataset("mbpp", "sanitized", trust_remote_code=True) dataset.save_to_disk(str(DATASET_PATH)) return dataset def load_mbpp(config: MbppConfig) -> Benchmark: """ Loads the MBPP benchmark, which consists of a series coding problems. Returns ------- Benchmark A Benchmark object containing a list of Task objects for the MBPP evaluation. """ dataset = _get_dataset() tasks = [] problems = [] for dataset_type in ["test", "train"]: problems += [ Problem( source_file=problem["source_file"], task_id=problem["task_id"], prompt=problem["prompt"], code=problem["code"], test_imports=problem["test_imports"], test_list=problem["test_list"], ) for index, problem in enumerate(dataset[dataset_type]) if index < config.__getattribute__(dataset_type + "_len") ] for problem in problems: prompt = Prompt( problem.prompt + "Please extend given function without changing it's declaration including arguments." ) tasks.append( Task( name=str(problem.task_id), initial_code=FilesDict({"main.py": problem.starting_code}), command=None, # Explicitly setting `None` because each assertion runs code prompt=prompt, assertions={ f"correct assertion {i}": MbppAssertion( assertion=assertion ).evaluate for i, assertion in enumerate(problem.test_list) }, ) ) return Benchmark( name="mbpp", tasks=tasks, ) ================================================ FILE: gpt_engineer/benchmark/benchmarks/mbpp/problem.py ================================================ from dataclasses import dataclass from typing import List @dataclass(frozen=True) class Problem: source_file: int task_id: str prompt: str code: str test_imports: str test_list: List[str] @property def starting_code(self) -> str: lines: List[str] = [] for line in self.code.split("\n"): lines.append(line) if line.startswith("def "): lines.append("pass # TODO: Implement method\n") break return "\n".join(lines) ================================================ FILE: gpt_engineer/benchmark/benchmarks/mbpp/problems.py ================================================ # TODO: Pick problems # Temporary testing against these problems PROBLEM_IDS = range(0, 100) ================================================ FILE: gpt_engineer/benchmark/default_bench_config.toml ================================================ # For apps, the maximal range is 0:5000 for both train and test [apps] active = true test_start_index = 0 test_end_index = 2 train_start_index = 0 train_end_index = 2 # For mbpp, the maximal range is 0:47 [mbpp] active = true test_len = 2 train_len = 2 [gptme] active = true ================================================ FILE: gpt_engineer/benchmark/run.py ================================================ """ Module for running benchmarks. This module defines functions to run benchmarks using a given agent and to print the results of the benchmark tasks. Functions --------- run : function Runs the benchmark tasks using the provided agent and returns a list of TaskResult objects. print_results : function Prints the results of the benchmark tasks to the console. """ import time from typing import List import yaml from gpt_engineer.benchmark.types import Assertable, Benchmark, TaskResult from gpt_engineer.core.base_agent import BaseAgent from gpt_engineer.core.default.disk_execution_env import DiskExecutionEnv def run( agent: BaseAgent, benchmark: Benchmark, verbose=False, ) -> List[TaskResult]: """ Runs the benchmark tasks using the provided agent and returns a list of TaskResult objects. Parameters ---------- agent : BaseAgent The agent to use for running the benchmark tasks. benchmark : Benchmark The benchmark containing the tasks to run. verbose : bool, default=False A flag to indicate whether to print verbose output during the benchmark. Returns ------- List[TaskResult] A list of TaskResult objects representing the results of the benchmark tasks. """ task_results = [] for task in benchmark.tasks: print(f"--> Running task: {task.name}\n") t0 = time.time() files_dict = agent.improve(task.initial_code, task.prompt) t1 = time.time() env = DiskExecutionEnv() env.upload(files_dict) if task.command: p = env.popen(task.command) stdout, stderr = p.communicate(benchmark.timeout) stdout, stderr = stdout.decode("utf-8"), stderr.decode("utf-8") else: p, stdout, stderr = None, None, None exec_result = Assertable( files=files_dict, env=env, process=p, stdout=stdout, stderr=stderr, ) task_results.append( TaskResult( task_name=task.name, assertion_results={ assertion_name: assertion(exec_result) for assertion_name, assertion in task.assertions.items() }, duration=t1 - t0, ) ) if verbose: print_results(task_results) return task_results def print_results(results: list[TaskResult]): """ Prints the results of the benchmark tasks to the console. Parameters ---------- results : list[TaskResult] A list of TaskResult objects representing the results of the benchmark tasks. Returns ------- None """ for task_result in results: print(f"\n--- Results for {task_result.task_name} ---") print(f"{task_result.task_name} ({task_result.duration:.2f}s)") for assertion_name, assertion_result in task_result.assertion_results.items(): checkmark = "✅" if assertion_result else "❌" print(f" {checkmark} {assertion_name}") print() success_rates = [task_result.success_rate for task_result in results] avg_success_rate = sum(success_rates) / len(results) total_time = sum(task_result.duration for task_result in results) correct_assertions = sum( sum( assertion_result for assertion_result in task_result.assertion_results.values() ) for task_result in results ) total_assertions = sum( len(task_result.assertion_results) for task_result in results ) correct_tasks = [ task_result for task_result in results if task_result.success_rate == 1 ] print("--- Results ---") print(f"Total time: {total_time:.2f}s") print(f"Completely correct tasks: {len(correct_tasks)}/{len(results)}") print(f"Total correct assertions: {correct_assertions}/{total_assertions}") print(f"Average success rate: {avg_success_rate * 100}% on {len(results)} tasks") print("--- Results ---") print() def export_yaml_results(yaml_path, complete_results, config): for results in complete_results.values(): correct_tasks = [ task_result for task_result in results["detailed"] if task_result["solved"] == 1.0 ] fraction_correct = len(correct_tasks) / len(results["detailed"]) results["fully_solved"] = fraction_correct complete_results["config"] = config with open(yaml_path, "w") as f: yaml.dump(complete_results, f, indent=4) ================================================ FILE: gpt_engineer/benchmark/types.py ================================================ """ Module defining types used in benchmarking. This module contains dataclass definitions for various types used throughout the benchmarking process, such as Assertable, Task, Benchmark, and TaskResult. Classes: Assertable: Represents an object that can be asserted against in a benchmark task. Assertion: Type alias for a callable that takes an Assertable and returns a boolean. Task: Represents a single task within a benchmark, including its assertions. Benchmark: Represents a collection of tasks used to evaluate a model's performance. TaskResult: Represents the result of running a single task within a benchmark. """ from dataclasses import dataclass from subprocess import Popen from typing import Callable, Dict, Optional from gpt_engineer.core.base_execution_env import BaseExecutionEnv from gpt_engineer.core.files_dict import FilesDict from gpt_engineer.core.prompt import Prompt @dataclass class Assertable: """ A class representing an object which can be asserted against. Attributes: files (FilesDict): The code files involved in the assertion. env (BaseExecutionEnv): The execution environment in which the code is run. process (Popen): The subprocess in which the code is run. stdout (str): The standard output from the code execution. stderr (str): The standard error from the code execution. """ files: FilesDict env: BaseExecutionEnv process: Optional[Popen] stdout: Optional[str] stderr: Optional[str] Assertion = Callable[[Assertable], bool] @dataclass class Task: name: str initial_code: Optional[FilesDict] command: Optional[str] prompt: Prompt assertions: Optional[Dict[str, Assertion]] @dataclass class Benchmark: """A benchmark is a collection of tasks that evaluate a model's performance.""" name: str tasks: list[Task] timeout: Optional[int] = None @dataclass class TaskResult: task_name: str assertion_results: dict[str, bool] duration: float # Returns success rate from 0.00 up to 1.00 @property def success_rate(self) -> float: if not self.assertion_results: return 0.0 succeeded = len( [result for result in self.assertion_results.values() if result is True] ) return succeeded / len(self.assertion_results) def to_dict(self) -> dict: out_dict = {key: value for key, value in self.__dict__.items()} out_dict["solved"] = self.success_rate return out_dict ================================================ FILE: gpt_engineer/core/__init__.py ================================================ ================================================ FILE: gpt_engineer/core/ai.py ================================================ """ AI Module This module provides an AI class that interfaces with language models to perform various tasks such as starting a conversation, advancing the conversation, and handling message serialization. It also includes backoff strategies for handling rate limit errors from the OpenAI API. Classes: AI: A class that interfaces with language models for conversation management and message serialization. Functions: serialize_messages(messages: List[Message]) -> str Serialize a list of messages to a JSON string. """ from __future__ import annotations import json import logging import os from pathlib import Path from typing import Any, List, Optional, Union import backoff import openai import pyperclip from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler from langchain.chat_models.base import BaseChatModel from langchain.schema import ( AIMessage, HumanMessage, SystemMessage, messages_from_dict, messages_to_dict, ) from langchain_anthropic import ChatAnthropic from langchain_openai import AzureChatOpenAI, ChatOpenAI from gpt_engineer.core.token_usage import TokenUsageLog # Type hint for a chat message Message = Union[AIMessage, HumanMessage, SystemMessage] # Set up logging logger = logging.getLogger(__name__) class AI: """ A class that interfaces with language models for conversation management and message serialization. This class provides methods to start and advance conversations, handle message serialization, and implement backoff strategies for rate limit errors when interacting with the OpenAI API. Attributes ---------- temperature : float The temperature setting for the language model. azure_endpoint : str The endpoint URL for the Azure-hosted language model. model_name : str The name of the language model to use. streaming : bool A flag indicating whether to use streaming for the language model. llm : BaseChatModel The language model instance for conversation management. token_usage_log : TokenUsageLog A log for tracking token usage during conversations. Methods ------- start(system: str, user: str, step_name: str) -> List[Message] Start the conversation with a system message and a user message. next(messages: List[Message], prompt: Optional[str], step_name: str) -> List[Message] Advances the conversation by sending message history to LLM and updating with the response. backoff_inference(messages: List[Message]) -> Any Perform inference using the language model with an exponential backoff strategy. serialize_messages(messages: List[Message]) -> str Serialize a list of messages to a JSON string. deserialize_messages(jsondictstr: str) -> List[Message] Deserialize a JSON string to a list of messages. _create_chat_model() -> BaseChatModel Create a chat model with the specified model name and temperature. """ def __init__( self, model_name="gpt-4-turbo", temperature=0.1, azure_endpoint=None, streaming=True, vision=False, ): """ Initialize the AI class. Parameters ---------- model_name : str, optional The name of the model to use, by default "gpt-4". temperature : float, optional The temperature to use for the model, by default 0.1. """ self.temperature = temperature self.azure_endpoint = azure_endpoint self.model_name = model_name self.streaming = streaming self.vision = ( ("vision-preview" in model_name) or ("gpt-4-turbo" in model_name and "preview" not in model_name) or ("claude" in model_name) ) self.llm = self._create_chat_model() self.token_usage_log = TokenUsageLog(model_name) logger.debug(f"Using model {self.model_name}") def start(self, system: str, user: Any, *, step_name: str) -> List[Message]: """ Start the conversation with a system message and a user message. Parameters ---------- system : str The content of the system message. user : str The content of the user message. step_name : str The name of the step. Returns ------- List[Message] The list of messages in the conversation. """ messages: List[Message] = [ SystemMessage(content=system), HumanMessage(content=user), ] return self.next(messages, step_name=step_name) def _extract_content(self, content): """ Extracts text content from a message, supporting both string and list types. Parameters ---------- content : Union[str, List[dict]] The content of a message, which could be a string or a list. Returns ------- str The extracted text content. """ if isinstance(content, str): return content elif isinstance(content, list) and content and "text" in content[0]: # Assuming the structure of list content is [{'type': 'text', 'text': 'Some text'}, ...] return content[0]["text"] else: return "" def _collapse_text_messages(self, messages: List[Message]): """ Combine consecutive messages of the same type into a single message, where if the message content is a list type, the first text element's content is taken. This method keeps `combined_content` as a string. This method iterates through the list of messages, combining consecutive messages of the same type by joining their content with a newline character. If the content is a list, it extracts text from the first text element's content. This reduces the number of messages and simplifies the conversation for processing. Parameters ---------- messages : List[Message] The list of messages to collapse. Returns ------- List[Message] The list of messages after collapsing consecutive messages of the same type. """ collapsed_messages = [] if not messages: return collapsed_messages previous_message = messages[0] combined_content = self._extract_content(previous_message.content) for current_message in messages[1:]: if current_message.type == previous_message.type: combined_content += "\n\n" + self._extract_content( current_message.content ) else: collapsed_messages.append( previous_message.__class__(content=combined_content) ) previous_message = current_message combined_content = self._extract_content(current_message.content) collapsed_messages.append(previous_message.__class__(content=combined_content)) return collapsed_messages def next( self, messages: List[Message], prompt: Optional[str] = None, *, step_name: str, ) -> List[Message]: """ Advances the conversation by sending message history to LLM and updating with the response. Parameters ---------- messages : List[Message] The list of messages in the conversation. prompt : Optional[str], optional The prompt to use, by default None. step_name : str The name of the step. Returns ------- List[Message] The updated list of messages in the conversation. """ if prompt: messages.append(HumanMessage(content=prompt)) logger.debug( "Creating a new chat completion: %s", "\n".join([m.pretty_repr() for m in messages]), ) if not self.vision: messages = self._collapse_text_messages(messages) response = self.backoff_inference(messages) self.token_usage_log.update_log( messages=messages, answer=response.content, step_name=step_name ) messages.append(response) logger.debug(f"Chat completion finished: {messages}") return messages @backoff.on_exception(backoff.expo, openai.RateLimitError, max_tries=7, max_time=45) def backoff_inference(self, messages): """ Perform inference using the language model while implementing an exponential backoff strategy. This function will retry the inference in case of a rate limit error from the OpenAI API. It uses an exponential backoff strategy, meaning the wait time between retries increases exponentially. The function will attempt to retry up to 7 times within a span of 45 seconds. Parameters ---------- messages : List[Message] A list of chat messages which will be passed to the language model for processing. callbacks : List[Callable] A list of callback functions that are triggered after each inference. These functions can be used for logging, monitoring, or other auxiliary tasks. Returns ------- Any The output from the language model after processing the provided messages. Raises ------ openai.error.RateLimitError If the number of retries exceeds the maximum or if the rate limit persists beyond the allotted time, the function will ultimately raise a RateLimitError. Example ------- >>> messages = [SystemMessage(content="Hello"), HumanMessage(content="How's the weather?")] >>> response = backoff_inference(messages) """ return self.llm.invoke(messages) # type: ignore @staticmethod def serialize_messages(messages: List[Message]) -> str: """ Serialize a list of messages to a JSON string. Parameters ---------- messages : List[Message] The list of messages to serialize. Returns ------- str The serialized messages as a JSON string. """ return json.dumps(messages_to_dict(messages)) @staticmethod def deserialize_messages(jsondictstr: str) -> List[Message]: """ Deserialize a JSON string to a list of messages. Parameters ---------- jsondictstr : str The JSON string to deserialize. Returns ------- List[Message] The deserialized list of messages. """ data = json.loads(jsondictstr) # Modify implicit is_chunk property to ALWAYS false # since Langchain's Message schema is stricter prevalidated_data = [ {**item, "tools": {**item.get("tools", {}), "is_chunk": False}} for item in data ] return list(messages_from_dict(prevalidated_data)) # type: ignore def _create_chat_model(self) -> BaseChatModel: """ Create a chat model with the specified model name and temperature. Parameters ---------- model : str The name of the model to create. temperature : float The temperature to use for the model. Returns ------- BaseChatModel The created chat model. """ if self.azure_endpoint: return AzureChatOpenAI( azure_endpoint=self.azure_endpoint, openai_api_version=os.getenv( "OPENAI_API_VERSION", "2024-05-01-preview" ), deployment_name=self.model_name, openai_api_type="azure", streaming=self.streaming, callbacks=[StreamingStdOutCallbackHandler()], ) elif "claude" in self.model_name: return ChatAnthropic( model=self.model_name, temperature=self.temperature, callbacks=[StreamingStdOutCallbackHandler()], streaming=self.streaming, max_tokens_to_sample=4096, ) elif self.vision: return ChatOpenAI( model=self.model_name, temperature=self.temperature, streaming=self.streaming, callbacks=[StreamingStdOutCallbackHandler()], max_tokens=4096, # vision models default to low max token limits ) else: return ChatOpenAI( model=self.model_name, temperature=self.temperature, streaming=self.streaming, callbacks=[StreamingStdOutCallbackHandler()], ) def serialize_messages(messages: List[Message]) -> str: return AI.serialize_messages(messages) class ClipboardAI(AI): # Ignore not init superclass def __init__(self, **_): # type: ignore self.vision = False self.token_usage_log = TokenUsageLog("clipboard_llm") @staticmethod def serialize_messages(messages: List[Message]) -> str: return "\n\n".join([f"{m.type}:\n{m.content}" for m in messages]) @staticmethod def multiline_input(): print("Enter/Paste your content. Ctrl-D or Ctrl-Z ( windows ) to save it.") content = [] while True: try: line = input() except EOFError: break content.append(line) return "\n".join(content) def next( self, messages: List[Message], prompt: Optional[str] = None, *, step_name: str, ) -> List[Message]: """ Not yet fully supported """ if prompt: messages.append(HumanMessage(content=prompt)) logger.debug(f"Creating a new chat completion: {messages}") msgs = self.serialize_messages(messages) pyperclip.copy(msgs) Path("clipboard.txt").write_text(msgs) print( "Messages copied to clipboard and written to clipboard.txt,", len(msgs), "characters in total", ) response = self.multiline_input() messages.append(AIMessage(content=response)) logger.debug(f"Chat completion finished: {messages}") return messages ================================================ FILE: gpt_engineer/core/base_agent.py ================================================ """ Base Agent Module This module provides an abstract base class for an agent that interacts with code. It defines the interface for agents capable of initializing and improving code based on a given prompt. Implementations of this class are expected to provide concrete methods for these actions. Classes: BaseAgent: Abstract base class for an agent that interacts with code. """ from abc import ABC, abstractmethod from gpt_engineer.core.files_dict import FilesDict from gpt_engineer.core.prompt import Prompt class BaseAgent(ABC): """ Abstract base class for an agent that interacts with code. Defines the interface for agents capable of initializing and improving code based on a given prompt. Implementations of this class are expected to provide concrete methods for these actions. """ @abstractmethod def init(self, prompt: Prompt) -> FilesDict: pass @abstractmethod def improve(self, files_dict: FilesDict, prompt: Prompt) -> FilesDict: pass ================================================ FILE: gpt_engineer/core/base_execution_env.py ================================================ from abc import ABC, abstractmethod from subprocess import Popen from typing import Optional, Tuple from gpt_engineer.core.files_dict import FilesDict class BaseExecutionEnv(ABC): """ Abstract base class for an execution environment capable of running code. This class defines the interface for execution environments that can execute commands, handle processes, and manage file uploads and downloads. """ @abstractmethod def run(self, command: str, timeout: Optional[int] = None) -> Tuple[str, str, int]: """ Runs a command in the execution environment. """ raise NotImplementedError @abstractmethod def popen(self, command: str) -> Popen: """ Runs a command in the execution environment. """ raise NotImplementedError @abstractmethod def upload(self, files: FilesDict) -> "BaseExecutionEnv": """ Uploads files to the execution environment. """ raise NotImplementedError @abstractmethod def download(self) -> FilesDict: """ Downloads files from the execution environment. """ raise NotImplementedError ================================================ FILE: gpt_engineer/core/base_memory.py ================================================ """ Base Memory Module This module provides a type alias for a mutable mapping that represents the base memory structure used in the GPT Engineer project. The base memory is a mapping from file names (as strings or Path objects) to their corresponding code content (as strings). Type Aliases: BaseMemory: A mutable mapping from file names to code content. """ from pathlib import Path from typing import MutableMapping, Union BaseMemory = MutableMapping[Union[str, Path], str] ================================================ FILE: gpt_engineer/core/chat_to_files.py ================================================ """ This Python script provides functionalities for parsing chat transcripts that contain file paths and code blocks, applying diffs to these files, and parsing unified git diff format strings. The script is designed to work within a larger system that involves processing and manipulating code files based on chat inputs and diff information. Key Components: - chat_to_files_dict: Parses a chat transcript, extracting file paths and associated code blocks, and organizes them into a FilesDict object, which is a custom dictionary format designed to hold file contents keyed by their paths. - apply_diffs: Takes a dictionary of Diff objects (which represent changes to be made to files) and a FilesDict object containing the current state of files. It applies the changes described by the Diff objects to the corresponding files in the FilesDict, updating the file contents as specified by the diffs. - parse_diffs: Parses a string containing diffs in the unified git diff format, extracting the changes described in the diffs and organizing them into a dictionary of Diff objects, keyed by the filename to which each diff applies. - parse_diff_block: Parses a single block of text from a diff string, translating it into a Diff object that represents the changes described in that block of text. This script is intended for use in environments where code collaboration or review is conducted through chat interfaces, allowing for the dynamic application of changes to code bases and the efficient handling of file and diff information in chat transcripts. """ import logging import re from typing import Dict, Tuple from regex import regex from gpt_engineer.core.diff import ADD, REMOVE, RETAIN, Diff, Hunk from gpt_engineer.core.files_dict import FilesDict, file_to_lines_dict # Initialize a logger for this module logger = logging.getLogger(__name__) def chat_to_files_dict(chat: str) -> FilesDict: """ Converts a chat string containing file paths and code blocks into a FilesDict object. Args: - chat (str): The chat string containing file paths and code blocks. Returns: - FilesDict: A dictionary with file paths as keys and code blocks as values. """ # Regex to match file paths and associated code blocks regex = r"(\S+)\n\s*```[^\n]*\n(.+?)```" matches = re.finditer(regex, chat, re.DOTALL) files_dict = FilesDict() for match in matches: # Clean and standardize the file path path = re.sub(r'[\:<>"|?*]', "", match.group(1)) path = re.sub(r"^\[(.*)\]$", r"\1", path) path = re.sub(r"^`(.*)`$", r"\1", path) path = re.sub(r"[\]\:]$", "", path) # Extract and clean the code content content = match.group(2) # Add the cleaned path and content to the FilesDict files_dict[path.strip()] = content.strip() return files_dict def apply_diffs(diffs: Dict[str, Diff], files: FilesDict) -> FilesDict: """ Applies diffs to the provided files. Args: - diffs (Dict[str, Diff]): A dictionary of diffs to apply, keyed by filename. - files (FilesDict): The original files to which diffs will be applied. Returns: - FilesDict: The updated files after applying diffs. """ files = FilesDict(files.copy()) REMOVE_FLAG = "" # Placeholder to mark lines for removal for diff in diffs.values(): if diff.is_new_file(): # If it's a new file, create it with the content from the diff files[diff.filename_post] = "\n".join( line[1] for hunk in diff.hunks for line in hunk.lines ) else: # Convert the file content to a dictionary of lines line_dict = file_to_lines_dict(files[diff.filename_pre]) for hunk in diff.hunks: current_line = hunk.start_line_pre_edit for line in hunk.lines: if line[0] == RETAIN: current_line += 1 elif line[0] == ADD: # Handle added lines current_line -= 1 if ( current_line in line_dict.keys() and line_dict[current_line] != REMOVE_FLAG ): line_dict[current_line] += "\n" + line[1] else: line_dict[current_line] = line[1] current_line += 1 elif line[0] == REMOVE: # Mark removed lines with REMOVE_FLAG line_dict[current_line] = REMOVE_FLAG current_line += 1 # Remove lines marked for removal line_dict = { key: line_content for key, line_content in line_dict.items() if REMOVE_FLAG not in line_content } # Reassemble the file content files[diff.filename_post] = "\n".join(line_dict.values()) return files def parse_diffs(diff_string: str, diff_timeout=3) -> dict: """ Parses a diff string in the unified git diff format. Args: - diff_string (str): The diff string to parse. Returns: - dict: A dictionary of Diff objects keyed by filename. """ # Regex to match individual diff blocks diff_block_pattern = regex.compile( r"```.*?\n\s*?--- .*?\n\s*?\+\+\+ .*?\n(?:@@ .*? @@\n(?:[-+ ].*?\n)*?)*?```", re.DOTALL, ) diffs = {} try: for block in diff_block_pattern.finditer(diff_string, timeout=diff_timeout): diff_block = block.group() # Parse individual diff blocks and update the diffs dictionary diff = parse_diff_block(diff_block) for filename, diff_obj in diff.items(): if filename not in diffs: diffs[filename] = diff_obj else: print( f"\nMultiple diffs found for {filename}. Only the first one is kept." ) except TimeoutError: print("gpt-engineer timed out while parsing git diff") if not diffs: print( "GPT did not provide any proposed changes. Please try to reselect the files for uploading and edit your prompt file." ) return diffs def parse_diff_block(diff_block: str) -> dict: """ Parses a block of diff text into a Diff object. Args: - diff_block (str): A single block of diff text. Returns: - dict: A dictionary containing a single Diff object keyed by the post-edit filename. """ lines = diff_block.strip().split("\n")[1:-1] # Exclude the opening and closing ``` diffs = {} current_diff = None hunk_lines = [] filename_pre = None filename_post = None hunk_header = None for line in lines: if line.startswith("--- "): # Pre-edit filename filename_pre = line[4:] elif line.startswith("+++ "): # Post-edit filename and initiation of a new Diff object if ( filename_post is not None and current_diff is not None and hunk_header is not None ): current_diff.hunks.append(Hunk(*hunk_header, hunk_lines)) hunk_lines = [] filename_post = line[4:] current_diff = Diff(filename_pre, filename_post) diffs[filename_post] = current_diff elif line.startswith("@@ "): # Start of a new hunk in the diff if hunk_lines and current_diff is not None and hunk_header is not None: current_diff.hunks.append(Hunk(*hunk_header, hunk_lines)) hunk_lines = [] hunk_header = parse_hunk_header(line) elif line.startswith("+"): # Added line hunk_lines.append((ADD, line[1:])) elif line.startswith("-"): # Removed line hunk_lines.append((REMOVE, line[1:])) else: # Retained line hunk_lines.append((RETAIN, line[1:])) # Append the last hunk if any if current_diff is not None and hunk_lines and hunk_header is not None: current_diff.hunks.append(Hunk(*hunk_header, hunk_lines)) return diffs def parse_hunk_header(header_line) -> Tuple[int, int, int, int]: """ Parses the header of a hunk from a diff. Args: - header_line (str): The header line of a hunk. Returns: - tuple: A tuple containing start and length information for pre- and post-edit. """ pattern = re.compile(r"^@@ -\d{1,},\d{1,} \+\d{1,},\d{1,} @@$") if not pattern.match(header_line): # Return a default value if the header does not match the expected format return 0, 0, 0, 0 pre, post = header_line.split(" ")[1:3] start_line_pre_edit, hunk_len_pre_edit = map(int, pre[1:].split(",")) start_line_post_edit, hunk_len_post_edit = map(int, post[1:].split(",")) return ( start_line_pre_edit, hunk_len_pre_edit, start_line_post_edit, hunk_len_post_edit, ) ================================================ FILE: gpt_engineer/core/default/__init__.py ================================================ ================================================ FILE: gpt_engineer/core/default/constants.py ================================================ """ Module defining constants used throughout the application. This module contains definitions of constants that are used across various components of the application to maintain consistency and ease of configuration. Constants --------- MAX_EDIT_REFINEMENT_STEPS : int The maximum number of refinement steps allowed when generating edit blocks. """ MAX_EDIT_REFINEMENT_STEPS = 2 ================================================ FILE: gpt_engineer/core/default/disk_execution_env.py ================================================ """ Module for managing the execution environment on the local disk. This module provides a class that handles the execution of code stored on the local file system. It includes methods for uploading files to the execution environment, running commands, and capturing the output. Classes ------- DiskExecutionEnv An execution environment that runs code on the local file system and captures the output of the execution. Imports ------- - subprocess: For running shell commands. - time: For timing the execution of commands. - Path: For handling file system paths. - Optional, Tuple, Union: For type annotations. - BaseExecutionEnv: For inheriting the base execution environment interface. - FileStore: For managing file storage. - FilesDict: For handling collections of files. """ import subprocess import time from pathlib import Path from typing import Optional, Tuple, Union from gpt_engineer.core.base_execution_env import BaseExecutionEnv from gpt_engineer.core.default.file_store import FileStore from gpt_engineer.core.files_dict import FilesDict class DiskExecutionEnv(BaseExecutionEnv): """ An execution environment that runs code on the local file system and captures the output of the execution. This class is responsible for executing code that is stored on disk. It ensures that the necessary entrypoint file exists and then runs the code using a subprocess. If the execution is interrupted by the user, it handles the interruption gracefully. Attributes ---------- store : FileStore An instance of FileStore that manages the storage of files in the execution environment. """ def __init__(self, path: Union[str, Path, None] = None): self.files = FileStore(path) def upload(self, files: FilesDict) -> "DiskExecutionEnv": self.files.push(files) return self def download(self) -> FilesDict: return self.files.pull() def popen(self, command: str) -> subprocess.Popen: p = subprocess.Popen( command, shell=True, cwd=self.files.working_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) return p def run(self, command: str, timeout: Optional[int] = None) -> Tuple[str, str, int]: start = time.time() print("\n--- Start of run ---") # while running, also print the stdout and stderr p = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.files.working_dir, text=True, shell=True, ) print("$", command) stdout_full, stderr_full = "", "" try: while p.poll() is None: assert p.stdout is not None assert p.stderr is not None stdout = p.stdout.readline() stderr = p.stderr.readline() if stdout: print(stdout, end="") stdout_full += stdout if stderr: print(stderr, end="") stderr_full += stderr if timeout and time.time() - start > timeout: print("Timeout!") p.kill() raise TimeoutError() except KeyboardInterrupt: print() print("Stopping execution.") print("Execution stopped.") p.kill() print() print("--- Finished run ---\n") return stdout_full, stderr_full, p.returncode ================================================ FILE: gpt_engineer/core/default/disk_memory.py ================================================ """ Disk Memory Module ================== This module provides a simple file-based key-value database system, where keys are represented as filenames and values are the contents of these files. The `DiskMemory` class is responsible for the CRUD operations on the database. Attributes ---------- None Functions --------- None Classes ------- DiskMemory A file-based key-value store where keys correspond to filenames and values to file contents. """ import base64 import json import shutil from datetime import datetime from pathlib import Path from typing import Any, Dict, Iterator, Optional, Union from gpt_engineer.core.base_memory import BaseMemory from gpt_engineer.tools.supported_languages import SUPPORTED_LANGUAGES # This class represents a simple database that stores its tools as files in a directory. class DiskMemory(BaseMemory): """ A file-based key-value store where keys correspond to filenames and values to file contents. This class provides an interface to a file-based database, leveraging file operations to facilitate CRUD-like interactions. It allows for quick checks on the existence of keys, retrieval of values based on keys, and setting new key-value pairs. Attributes ---------- path : Path The directory path where the database files are stored. """ def __init__(self, path: Union[str, Path]): """ Initialize the DiskMemory class with a specified path. Parameters ---------- path : str or Path The path to the directory where the database files will be stored. """ self.path: Path = Path(path).absolute() self.path.mkdir(parents=True, exist_ok=True) def __contains__(self, key: str) -> bool: """ Determine whether the database contains a file with the specified key. Parameters ---------- key : str The key (filename) to check for existence in the database. Returns ------- bool Returns True if the file exists, False otherwise. """ return (self.path / key).is_file() def __getitem__(self, key: str) -> str: """ Retrieve the content of a file in the database corresponding to the given key. If the file is an image with a .png or .jpeg extension, it returns the content in Base64-encoded string format. Parameters ---------- key : str The key (filename) whose content is to be retrieved. Returns ------- str The content of the file associated with the key, or Base64-encoded string if it's a .png or .jpeg file. Raises ------ KeyError If the file corresponding to the key does not exist in the database. """ full_path = self.path / key if not full_path.is_file(): raise KeyError(f"File '{key}' could not be found in '{self.path}'") if full_path.suffix in [".png", ".jpeg", ".jpg"]: with full_path.open("rb") as image_file: encoded_string = base64.b64encode(image_file.read()).decode("utf-8") mime_type = "image/png" if full_path.suffix == ".png" else "image/jpeg" return f"data:{mime_type};base64,{encoded_string}" else: with full_path.open("r", encoding="utf-8") as f: return f.read() def get(self, key: str, default: Optional[Any] = None) -> Any: """ Retrieve the content of a file in the database, or return a default value if not found. Parameters ---------- key : str The key (filename) whose content is to be retrieved. default : Any, optional The default value to return if the file does not exist. Default is None. Returns ------- Any The content of the file if it exists, a new DiskMemory instance if the key corresponds to a directory. """ item_path = self.path / key try: if item_path.is_file(): return self[key] elif item_path.is_dir(): return DiskMemory(item_path) else: return default except: return default def __setitem__(self, key: Union[str, Path], val: str) -> None: """ Set or update the content of a file in the database corresponding to the given key. Parameters ---------- key : str or Path The key (filename) where the content is to be set. val : str The content to be written to the file. Raises ------ ValueError If the key attempts to access a parent path. TypeError If the value is not a string. """ if str(key).startswith("../"): raise ValueError(f"File name {key} attempted to access parent path.") if not isinstance(val, str): raise TypeError("val must be str") full_path = self.path / key full_path.parent.mkdir(parents=True, exist_ok=True) full_path.write_text(val, encoding="utf-8") def __delitem__(self, key: Union[str, Path]) -> None: """ Delete a file or directory from the database corresponding to the given key. Parameters ---------- key : str or Path The key (filename or directory name) to be deleted. Raises ------ KeyError If the file or directory corresponding to the key does not exist in the database. """ item_path = self.path / key if not item_path.exists(): raise KeyError(f"Item '{key}' could not be found in '{self.path}'") if item_path.is_file(): item_path.unlink() elif item_path.is_dir(): shutil.rmtree(item_path) def __iter__(self) -> Iterator[str]: """ Iterate over the keys (filenames) in the database. Yields ------ Iterator[str] An iterator over the sorted list of keys (filenames) in the database. """ return iter( sorted( str(item.relative_to(self.path)) for item in sorted(self.path.rglob("*")) if item.is_file() ) ) def __len__(self) -> int: """ Get the number of files in the database. Returns ------- int The number of files in the database. """ return len(list(self.__iter__())) def _supported_files(self) -> str: valid_extensions = { ext for lang in SUPPORTED_LANGUAGES for ext in lang["extensions"] } file_paths = [ str(item) for item in self if Path(item).is_file() and Path(item).suffix in valid_extensions ] return "\n".join(file_paths) def _all_files(self) -> str: file_paths = [str(item) for item in self if Path(item).is_file()] return "\n".join(file_paths) def to_path_list_string(self, supported_code_files_only: bool = False) -> str: """ Generate a string representation of the file paths in the database. Parameters ---------- supported_code_files_only : bool, optional If True, filter the list to include only supported code file extensions. Default is False. Returns ------- str A newline-separated string of file paths. """ if supported_code_files_only: return self._supported_files() else: return self._all_files() def to_dict(self) -> Dict[Union[str, Path], str]: """ Convert the database contents to a dictionary. Returns ------- Dict[Union[str, Path], str] A dictionary with keys as filenames and values as file contents. """ return {file_path: self[file_path] for file_path in self} def to_json(self) -> str: """ Serialize the database contents to a JSON string. Returns ------- str A JSON string representation of the database contents. """ return json.dumps(self.to_dict()) def log(self, key: Union[str, Path], val: str) -> None: """ Append to a file or create and write to it if it doesn't exist. Parameters ---------- key : str or Path The key (filename) where the content is to be appended. val : str The content to be appended to the file. """ if str(key).startswith("../"): raise ValueError(f"File name {key} attempted to access parent path.") if not isinstance(val, str): raise TypeError("val must be str") full_path = self.path / "logs" / key full_path.parent.mkdir(parents=True, exist_ok=True) # Touch if it doesnt exist if not full_path.exists(): full_path.touch() with open(full_path, "a", encoding="utf-8") as file: file.write(f"\n{datetime.now().isoformat()}\n") file.write(val + "\n") def archive_logs(self): """ Moves all logs to archive directory based on current timestamp """ if "logs" in self: archive_dir = ( self.path / f"logs_{datetime.now().strftime('%Y-%m-%d-%H-%M-%S')}" ) shutil.move(self.path / "logs", archive_dir) ================================================ FILE: gpt_engineer/core/default/file_store.py ================================================ import tempfile from pathlib import Path from typing import Union from gpt_engineer.core.files_dict import FilesDict from gpt_engineer.core.linting import Linting class FileStore: """ Module for managing file storage in a temporary directory. This module provides a class that manages the storage of files in a temporary directory. It includes methods for uploading files to the directory and downloading them as a collection of files. Classes ------- FileStore Manages file storage in a temporary directory, allowing for upload and download of files. Imports ------- - tempfile: For creating temporary directories. - Path: For handling file system paths. - Union: For type annotations. - FilesDict: For handling collections of files. """ def __init__(self, path: Union[str, Path, None] = None): if path is None: path = Path(tempfile.mkdtemp(prefix="gpt-engineer-")) self.working_dir = Path(path) self.working_dir.mkdir(parents=True, exist_ok=True) self.id = self.working_dir.name.split("-")[-1] def push(self, files: FilesDict): for name, content in files.items(): path = self.working_dir / name path.parent.mkdir(parents=True, exist_ok=True) with open(path, "w") as f: f.write(content) return self def linting(self, files: FilesDict) -> FilesDict: # lint the code linting = Linting() return linting.lint_files(files) def pull(self) -> FilesDict: files = {} for path in self.working_dir.glob("**/*"): if path.is_file(): with open(path, "r") as f: try: content = f.read() except UnicodeDecodeError: content = "binary file" files[str(path.relative_to(self.working_dir))] = content return FilesDict(files) ================================================ FILE: gpt_engineer/core/default/paths.py ================================================ """ Module defining file system paths used by the application. This module contains definitions of file system paths that are used throughout the application to locate and manage various files and directories, such as logs, memory, and preprompts. Constants --------- META_DATA_REL_PATH : str The relative path to the directory where metadata is stored. MEMORY_REL_PATH : str The relative path to the directory where memory-related files are stored. CODE_GEN_LOG_FILE : str The filename for the log file that contains all output from code generation. DEBUG_LOG_FILE : str The filename for the log file that contains debug information. ENTRYPOINT_FILE : str The filename for the entrypoint script that is executed to run the application. ENTRYPOINT_LOG_FILE : str The filename for the log file that contains the chat related to entrypoint generation. PREPROMPTS_PATH : Path The file system path to the directory containing preprompt files. Functions --------- memory_path : function Constructs the full path to the memory directory based on a given base path. metadata_path : function Constructs the full path to the metadata directory based on a given base path. """ import os from pathlib import Path META_DATA_REL_PATH = ".gpteng" MEMORY_REL_PATH = os.path.join(META_DATA_REL_PATH, "memory") CODE_GEN_LOG_FILE = "all_output.txt" IMPROVE_LOG_FILE = "improve.txt" DIFF_LOG_FILE = "diff_errors.txt" DEBUG_LOG_FILE = "debug_log_file.txt" ENTRYPOINT_FILE = "run.sh" ENTRYPOINT_LOG_FILE = "gen_entrypoint_chat.txt" ENTRYPOINT_FILE = "run.sh" PREPROMPTS_PATH = Path(__file__).parent.parent.parent / "preprompts" def memory_path(path): """ Constructs the full path to the memory directory based on a given base path. Parameters ---------- path : str The base path to append the memory directory to. Returns ------- str The full path to the memory directory. """ return os.path.join(path, MEMORY_REL_PATH) def metadata_path(path): """ Constructs the full path to the metadata directory based on a given base path. Parameters ---------- path : str The base path to append the metadata directory to. Returns ------- str The full path to the metadata directory. """ return os.path.join(path, META_DATA_REL_PATH) ================================================ FILE: gpt_engineer/core/default/simple_agent.py ================================================ """ Module for defining a simple agent that uses AI to manage code generation and improvement. This module provides a class that represents an agent capable of initializing and improving a codebase using AI. It handles interactions with the AI model, memory, and execution environment to generate and refine code based on user prompts. """ import tempfile from typing import Optional from gpt_engineer.core.ai import AI from gpt_engineer.core.base_agent import BaseAgent from gpt_engineer.core.base_execution_env import BaseExecutionEnv from gpt_engineer.core.base_memory import BaseMemory from gpt_engineer.core.default.disk_execution_env import DiskExecutionEnv from gpt_engineer.core.default.disk_memory import DiskMemory from gpt_engineer.core.default.paths import PREPROMPTS_PATH, memory_path from gpt_engineer.core.default.steps import gen_code, gen_entrypoint, improve_fn from gpt_engineer.core.files_dict import FilesDict from gpt_engineer.core.preprompts_holder import PrepromptsHolder from gpt_engineer.core.prompt import Prompt class SimpleAgent(BaseAgent): """ An agent that uses AI to generate and improve code based on a given prompt. This agent is capable of initializing a codebase from a prompt and improving an existing codebase based on user input. It uses an AI model to generate and refine code, and it interacts with a repository and an execution environment to manage and execute the code. Attributes ---------- memory : BaseMemory The memory interface where the code and related data are stored. execution_env : BaseExecutionEnv The execution environment in which the code is executed. ai : AI The AI model used for generating and improving code. preprompts_holder : PrepromptsHolder The holder for preprompt messages that guide the AI model. """ def __init__( self, memory: BaseMemory, execution_env: BaseExecutionEnv, ai: AI = None, preprompts_holder: PrepromptsHolder = None, ): self.preprompts_holder = preprompts_holder or PrepromptsHolder(PREPROMPTS_PATH) self.memory = memory self.execution_env = execution_env self.ai = ai or AI() @classmethod def with_default_config( cls, path: str, ai: AI = None, preprompts_holder: PrepromptsHolder = None ): return cls( memory=DiskMemory(memory_path(path)), execution_env=DiskExecutionEnv(), ai=ai, preprompts_holder=preprompts_holder or PrepromptsHolder(PREPROMPTS_PATH), ) def init(self, prompt: Prompt) -> FilesDict: files_dict = gen_code(self.ai, prompt, self.memory, self.preprompts_holder) entrypoint = gen_entrypoint( self.ai, prompt, files_dict, self.memory, self.preprompts_holder ) combined_dict = {**files_dict, **entrypoint} files_dict = FilesDict(combined_dict) return files_dict def improve( self, files_dict: FilesDict, prompt: Prompt, execution_command: Optional[str] = None, ) -> FilesDict: files_dict = improve_fn( self.ai, prompt, files_dict, self.memory, self.preprompts_holder ) return files_dict def default_config_agent(): """ Creates an instance of SimpleAgent with default configuration. Returns ------- SimpleAgent An instance of SimpleAgent with a temporary directory as its base path. """ return SimpleAgent.with_default_config(tempfile.mkdtemp()) ================================================ FILE: gpt_engineer/core/default/steps.py ================================================ """ Module for defining the steps involved in generating and improving code using AI. This module provides functions that represent different steps in the process of generating and improving code using an AI model. These steps include generating code from a prompt, creating an entrypoint for the codebase, executing the entrypoint, and refining code edits. Functions --------- curr_fn : function Returns the name of the current function. setup_sys_prompt : function Sets up the system prompt for generating code. gen_code : function Generates code from a prompt using AI and returns the generated files. gen_entrypoint : function Generates an entrypoint for the codebase and returns the entrypoint files. execute_entrypoint : function Executes the entrypoint of the codebase. setup_sys_prompt_existing_code : function Sets up the system prompt for improving existing code. improve : function Improves the code based on user input and returns the updated files. """ import inspect import io import re import sys import traceback from pathlib import Path from typing import List, MutableMapping, Union from langchain.schema import HumanMessage, SystemMessage from termcolor import colored from gpt_engineer.core.ai import AI from gpt_engineer.core.base_execution_env import BaseExecutionEnv from gpt_engineer.core.base_memory import BaseMemory from gpt_engineer.core.chat_to_files import apply_diffs, chat_to_files_dict, parse_diffs from gpt_engineer.core.default.constants import MAX_EDIT_REFINEMENT_STEPS from gpt_engineer.core.default.paths import ( CODE_GEN_LOG_FILE, DEBUG_LOG_FILE, DIFF_LOG_FILE, ENTRYPOINT_FILE, ENTRYPOINT_LOG_FILE, IMPROVE_LOG_FILE, ) from gpt_engineer.core.files_dict import FilesDict, file_to_lines_dict from gpt_engineer.core.preprompts_holder import PrepromptsHolder from gpt_engineer.core.prompt import Prompt def curr_fn() -> str: """ Returns the name of the current function. Returns ------- str The name of the function that called this function. """ return inspect.stack()[1].function def setup_sys_prompt(preprompts: MutableMapping[Union[str, Path], str]) -> str: """ Sets up the system prompt for generating code. Parameters ---------- preprompts : MutableMapping[Union[str, Path], str] A mapping of preprompt messages to guide the AI model. Returns ------- str The system prompt message for the AI model. """ return ( preprompts["roadmap"] + preprompts["generate"].replace("FILE_FORMAT", preprompts["file_format"]) + "\nUseful to know:\n" + preprompts["philosophy"] ) def setup_sys_prompt_existing_code( preprompts: MutableMapping[Union[str, Path], str] ) -> str: """ Sets up the system prompt for improving existing code. Parameters ---------- preprompts : MutableMapping[Union[str, Path], str] A mapping of preprompt messages to guide the AI model. Returns ------- str The system prompt message for the AI model to improve existing code. """ return ( preprompts["roadmap"] + preprompts["improve"].replace("FILE_FORMAT", preprompts["file_format_diff"]) + "\nUseful to know:\n" + preprompts["philosophy"] ) def gen_code( ai: AI, prompt: Prompt, memory: BaseMemory, preprompts_holder: PrepromptsHolder ) -> FilesDict: """ Generates code from a prompt using AI and returns the generated files. Parameters ---------- ai : AI The AI model used for generating code. prompt : str The user prompt to generate code from. memory : BaseMemory The memory interface where the code and related data are stored. preprompts_holder : PrepromptsHolder The holder for preprompt messages that guide the AI model. Returns ------- FilesDict A dictionary of file names to their respective source code content. """ preprompts = preprompts_holder.get_preprompts() messages = ai.start( setup_sys_prompt(preprompts), prompt.to_langchain_content(), step_name=curr_fn() ) chat = messages[-1].content.strip() memory.log(CODE_GEN_LOG_FILE, "\n\n".join(x.pretty_repr() for x in messages)) files_dict = chat_to_files_dict(chat) return files_dict def gen_entrypoint( ai: AI, prompt: Prompt, files_dict: FilesDict, memory: BaseMemory, preprompts_holder: PrepromptsHolder, ) -> FilesDict: """ Generates an entrypoint for the codebase and returns the entrypoint files. Parameters ---------- ai : AI The AI model used for generating the entrypoint. files_dict : FilesDict The dictionary of file names to their respective source code content. memory : BaseMemory The memory interface where the code and related data are stored. preprompts_holder : PrepromptsHolder The holder for preprompt messages that guide the AI model. Returns ------- FilesDict A dictionary containing the entrypoint file. """ user_prompt = prompt.entrypoint_prompt if not user_prompt: user_prompt = """ Make a unix script that a) installs dependencies b) runs all necessary parts of the codebase (in parallel if necessary) """ preprompts = preprompts_holder.get_preprompts() messages = ai.start( system=(preprompts["entrypoint"]), user=user_prompt + "\nInformation about the codebase:\n\n" + files_dict.to_chat(), step_name=curr_fn(), ) print() chat = messages[-1].content.strip() regex = r"```\S*\n(.+?)```" matches = re.finditer(regex, chat, re.DOTALL) entrypoint_code = FilesDict( {ENTRYPOINT_FILE: "\n".join(match.group(1) for match in matches)} ) memory.log(ENTRYPOINT_LOG_FILE, "\n\n".join(x.pretty_repr() for x in messages)) return entrypoint_code def execute_entrypoint( ai: AI, execution_env: BaseExecutionEnv, files_dict: FilesDict, prompt: Prompt = None, preprompts_holder: PrepromptsHolder = None, memory: BaseMemory = None, ) -> FilesDict: """ Executes the entrypoint of the codebase. Parameters ---------- ai : AI The AI model used for generating the entrypoint. execution_env : BaseExecutionEnv The execution environment in which the code is executed. files_dict : FilesDict The dictionary of file names to their respective source code content. preprompts_holder : PrepromptsHolder, optional The holder for preprompt messages that guide the AI model. Returns ------- FilesDict The dictionary of file names to their respective source code content after execution. """ if ENTRYPOINT_FILE not in files_dict: raise FileNotFoundError( "The required entrypoint " + ENTRYPOINT_FILE + " does not exist in the code." ) command = files_dict[ENTRYPOINT_FILE] print() print( colored( "Do you want to execute this code? (Y/n)", "red", ) ) print() print(command) print() if input("").lower() not in ["", "y", "yes"]: print("Ok, not executing the code.") return files_dict print("Executing the code...") print() print( colored( "Note: If it does not work as expected, consider running the code" + " in another way than above.", "green", ) ) print() print("You can press ctrl+c *once* to stop the execution.") print() execution_env.upload(files_dict).run(f"bash {ENTRYPOINT_FILE}") return files_dict def improve_fn( ai: AI, prompt: Prompt, files_dict: FilesDict, memory: BaseMemory, preprompts_holder: PrepromptsHolder, diff_timeout=3, ) -> FilesDict: """ Improves the code based on user input and returns the updated files. Parameters ---------- ai : AI The AI model used for improving code. prompt :str The user prompt to improve the code. files_dict : FilesDict The dictionary of file names to their respective source code content. memory : BaseMemory The memory interface where the code and related data are stored. preprompts_holder : PrepromptsHolder The holder for preprompt messages that guide the AI model. Returns ------- FilesDict The dictionary of file names to their respective updated source code content. """ preprompts = preprompts_holder.get_preprompts() messages = [ SystemMessage(content=setup_sys_prompt_existing_code(preprompts)), ] # Add files as input messages.append(HumanMessage(content=f"{files_dict.to_chat()}")) messages.append(HumanMessage(content=prompt.to_langchain_content())) memory.log( DEBUG_LOG_FILE, "UPLOADED FILES:\n" + files_dict.to_log() + "\nPROMPT:\n" + prompt.text, ) return _improve_loop(ai, files_dict, memory, messages, diff_timeout=diff_timeout) def _improve_loop( ai: AI, files_dict: FilesDict, memory: BaseMemory, messages: List, diff_timeout=3 ) -> FilesDict: messages = ai.next(messages, step_name=curr_fn()) files_dict, errors = salvage_correct_hunks( messages, files_dict, memory, diff_timeout=diff_timeout ) retries = 0 while errors and retries < MAX_EDIT_REFINEMENT_STEPS: messages.append( HumanMessage( content="Some previously produced diffs were not on the requested format, or the code part was not found in the code. Details:\n" + "\n".join(errors) + "\n Only rewrite the problematic diffs, making sure that the failing ones are now on the correct format and can be found in the code. Make sure to not repeat past mistakes. \n" ) ) messages = ai.next(messages, step_name=curr_fn()) files_dict, errors = salvage_correct_hunks( messages, files_dict, memory, diff_timeout ) retries += 1 return files_dict def salvage_correct_hunks( messages: List, files_dict: FilesDict, memory: BaseMemory, diff_timeout=3 ) -> tuple[FilesDict, List[str]]: error_messages = [] ai_response = messages[-1].content.strip() diffs = parse_diffs(ai_response, diff_timeout=diff_timeout) # validate and correct diffs for _, diff in diffs.items(): # if diff is a new file, validation and correction is unnecessary if not diff.is_new_file(): problems = diff.validate_and_correct( file_to_lines_dict(files_dict[diff.filename_pre]) ) error_messages.extend(problems) files_dict = apply_diffs(diffs, files_dict) memory.log(IMPROVE_LOG_FILE, "\n\n".join(x.pretty_repr() for x in messages)) memory.log(DIFF_LOG_FILE, "\n\n".join(error_messages)) return files_dict, error_messages class Tee(object): def __init__(self, *files): self.files = files def write(self, obj): for file in self.files: file.write(obj) def flush(self): for file in self.files: file.flush() def handle_improve_mode(prompt, agent, memory, files_dict, diff_timeout=3): captured_output = io.StringIO() old_stdout = sys.stdout sys.stdout = Tee(sys.stdout, captured_output) try: files_dict = agent.improve(files_dict, prompt, diff_timeout=diff_timeout) except Exception as e: print( f"Error while improving the project: {e}\nCould you please upload the debug_log_file.txt in {memory.path}/logs folder to github?\nFULL STACK TRACE:\n" ) traceback.print_exc(file=sys.stdout) # Print the full stack trace finally: # Reset stdout sys.stdout = old_stdout # Get the captured output captured_string = captured_output.getvalue() print(captured_string) memory.log(DEBUG_LOG_FILE, "\nCONSOLE OUTPUT:\n" + captured_string) return files_dict ================================================ FILE: gpt_engineer/core/diff.py ================================================ """ File Overview: This Python module is designed for processing and analyzing diffs in source code files. Diffs represent the changes between two versions of a file, which are crucial in version control systems for tracking file modifications. The module focuses on the detailed examination of these diffs, enabling users to understand, validate, and correct changes between file versions. Key Features: 1. The `Hunk` class encapsulates a contiguous block of changes within a file. It includes detailed information such as start lines before and after edits, lengths of change blocks, and specific line changes categorized as additions, deletions, or unchanged. 2. The `Diff` class represents a complete set of changes across a file and may contain multiple `Hunk` objects. It facilitates operations like generating string representations of diffs, and validating and correcting hunks based on the original file content. 3. Functions within the module allow for the validation of hunks against original files, identifying mismatches, and making necessary corrections. This feature ensures that diffs are accurate and reflect true changes. 4. Utility functions `is_similar` and `count_ratio` offer the capability to compare strings for similarity, accounting for variations in spacing and case. This aids in the validation process by allowing a flexible comparison of code lines. Dependencies: - `logging`: Utilized for logging warnings and errors encountered during the validation and correction process. - `collections.Counter`: Used for counting occurrences of characters in strings, supporting the string similarity assessment functions. Functions and Classes: 1. `Hunk`: Class representing a block of changes within a file, with methods for managing and validating these changes. 2. `Diff`: Class representing the entire set of changes in a file, containing multiple `Hunk` instances and methods for overall diff management. 3. `is_similar(str1, str2, similarity_threshold)`: Function to compare two strings for similarity, useful in validating line changes in hunks. 4. `count_ratio(str1, str2)`: Function that computes the ratio of common characters to the length of the longer string, aiding in the assessment of line similarity. This module is essential for developers and teams utilizing version control systems, providing tools for a deeper analysis and correction of diffs, ensuring the integrity and accuracy of code changes. """ import logging from collections import Counter from typing import List RETAIN = "retain" ADD = "add" REMOVE = "remove" class Hunk: """ Represents a section of a file diff, containing changes made to that section. Attributes: start_line_pre_edit (int): The starting line number in the original file. hunk_len_pre_edit (int): The length of the hunk in the original file. start_line_post_edit (int): The starting line number in the edited file. hunk_len_post_edit (int): The length of the hunk in the edited file. lines (list): A list of tuples representing the lines in the hunk and their types (RETAIN, ADD, REMOVE). category_counts (dict): A count of lines by their type. is_new_file (bool): Flag indicating if the hunk represents a new file. """ def __init__( self, start_line_pre_edit, hunk_len_pre_edit, start_line_post_edit, hunk_len_post_edit, lines, ) -> None: self.start_line_pre_edit = start_line_pre_edit self.hunk_len_pre_edit = hunk_len_pre_edit self.start_line_post_edit = start_line_post_edit self.hunk_len_post_edit = hunk_len_post_edit self.category_counts = {RETAIN: 0, ADD: 0, REMOVE: 0} self.lines = list() self.add_lines(lines) self.forward_block_len = 10 # Note that this assumption should not be done on hunk level, however, if the below is true, no validation is possible anyway. if self.category_counts[RETAIN] == 0 and self.category_counts[REMOVE] == 0: self.is_new_file = True else: self.is_new_file = False def add_retained_line(self, line, index) -> None: """Adds a retained line to the hunk at the specified index.""" self.lines.insert(index, (RETAIN, line)) self.category_counts[RETAIN] += 1 def relabel_line(self, index, new_label) -> None: """Changes the label of a line at the specified index.""" old_label = self.lines[index][0] self.lines[index] = (new_label, self.lines[index][1]) self.category_counts[old_label] -= 1 self.category_counts[new_label] += 1 def pop_line(self, line, index) -> None: """Removes a line from the hunk at the specified index.""" self.lines.pop(index) assert self.category_counts[line[0]] > 0 self.category_counts[line[0]] -= 1 def add_lines(self, new_lines) -> None: """Adds multiple lines to the hunk.""" for line in new_lines: self.lines.append(line) self.category_counts[line[0]] += 1 def hunk_to_string(self) -> str: """Converts the hunk to a string representation.""" string = f"@@ -{self.start_line_pre_edit},{self.hunk_len_pre_edit} +{self.start_line_post_edit},{self.hunk_len_post_edit} @@\n" for line_type, line_content in self.lines: line_prefix = ( " " if line_type == RETAIN else "+" if line_type == ADD else "-" ) string += f"{line_prefix}{line_content}\n" return string def make_forward_block(self, hunk_ind: int, forward_block_len) -> str: """Creates a block of lines for forward comparison.""" forward_lines = [ line[1] for line in self.lines[hunk_ind:] if not line[0] == ADD ] forward_block = "\n".join(forward_lines[0:forward_block_len]) return forward_block def check_start_line(self, lines_dict: dict) -> bool: """Check if the starting line of a hunk is present in the original code and returns a boolean value accordingly.""" if self.is_new_file: # this hunk cannot be falsified and is by definition true return True if self.start_line_pre_edit in lines_dict: # check the location of the actual starting line: is_similar(self.lines[0][1], lines_dict[self.start_line_pre_edit]) else: pass def find_start_line(self, lines_dict: dict, problems: list) -> bool: """Finds the starting line of the hunk in the original code and returns a boolean value accordingly. If the starting line is not found, it appends a problem message to the problems list.""" # ToDo handle the case where the start line is 0 or 1 characters separately if self.lines[0][0] == ADD: # handle the case where the start line is an add start_line = None # find the first line that is not an add for index, line in enumerate(self.lines): if line[0] != ADD: for line_number, line_content in lines_dict.items(): # if the line is similar to a non-blank line in line_dict, we can pick the line prior to it if is_similar(line[1], line_content) and line[1] != "": start_line = line_number - 1 break # if the start line is not found, append a problem message if start_line is None: problems.append( f"In {self.hunk_to_string()}:can not find the starting line of the diff" ) return False else: # the line prior to the start line is found now we insert it to the first place as the start line self.start_line_pre_edit = start_line retain_line = lines_dict.get(start_line, "") if retain_line: self.add_retained_line(lines_dict[start_line], 0) return self.validate_and_correct(lines_dict, problems) else: problems.append( f"In {self.hunk_to_string()}:The starting line of the diff {self.hunk_to_string()} does not exist in the code" ) return False pot_start_lines = { key: is_similar(self.lines[0][1], line) for key, line in lines_dict.items() } sum_of_matches = sum(pot_start_lines.values()) if sum_of_matches == 0: # before we go any further, we should check if it's a comment from LLM if self.lines[0][1].count("#") > 0: # if it is, we can mark it as an ADD lines self.relabel_line(0, ADD) # and restart the validation at the next line return self.validate_and_correct(lines_dict, problems) else: problems.append( f"In {self.hunk_to_string()}:The starting line of the diff {self.hunk_to_string()} does not exist in the code" ) return False elif sum_of_matches == 1: start_ind = list(pot_start_lines.keys())[ list(pot_start_lines.values()).index(True) ] # lines are one indexed else: logging.warning("multiple candidates for starting index") # ToDo handle all the cases better again here. Smartest choice is that, for each candidate check match to the next line etc (recursively) start_ind = list(pot_start_lines.keys())[ list(pot_start_lines.values()).index(True) ] self.start_line_pre_edit = start_ind # This should now be fulfilled by default assert is_similar(self.lines[0][1], lines_dict[self.start_line_pre_edit]) return True def validate_lines(self, lines_dict: dict, problems: list) -> bool: """Validates the lines of the hunk against the original file and returns a boolean value accordingly. If the lines do not match, it appends a problem message to the problems list.""" hunk_ind = 0 file_ind = self.start_line_pre_edit # make an orig hunk lines for logging # orig_hunk_lines = deepcopy(self.lines) while hunk_ind < len(self.lines) and file_ind <= max(lines_dict): if self.lines[hunk_ind][0] == ADD: # this cannot be validated, jump one index hunk_ind += 1 elif not is_similar(self.lines[hunk_ind][1], lines_dict[file_ind]): # before we go any further, we should relabel the comment from LLM if self.lines[hunk_ind][1].count("#") > 0: self.relabel_line(hunk_ind, ADD) continue # make a forward block from the code for comparisons forward_code = "\n".join( [ lines_dict[ind] for ind in range( file_ind, min( file_ind + self.forward_block_len, max(lines_dict.keys()), ), ) ] ) # make the original forward block for quantitative comparison forward_block = self.make_forward_block( hunk_ind, self.forward_block_len ) orig_count_ratio = count_ratio(forward_block, forward_code) # Here we have 2 cases # 1) some lines were simply skipped in the diff and we should add them to the diff # If this is the case, adding the line to the diff, should give an improved forward diff forward_block_missing_line = self.make_forward_block( hunk_ind, self.forward_block_len - 1 ) # insert the missing line in front of the block forward_block_missing_line = "\n".join( [lines_dict[file_ind], forward_block_missing_line] ) missing_line_count_ratio = count_ratio( forward_block_missing_line, forward_code ) # 2) Additional lines, not belonging to the code were added to the diff forward_block_false_line = self.make_forward_block( hunk_ind + 1, self.forward_block_len ) false_line_count_ratio = count_ratio( forward_block_false_line, forward_code ) if ( orig_count_ratio >= missing_line_count_ratio and orig_count_ratio >= false_line_count_ratio ): problems.append( f"In Hunk:{self.hunk_to_string()}, there was at least one mismatch." ) return False elif missing_line_count_ratio > false_line_count_ratio: self.add_retained_line(lines_dict[file_ind], hunk_ind) hunk_ind += 1 file_ind += 1 # NOTE: IF THE LLM SKIPS SOME LINES AND HAS ADDs ADJACENT TO THE SKIPPED BLOCK, # WE CANNOT KNOW WHETHER THE ADDs SHOULD BE BEFORE OR AFTER THE BLOCK. WE OPT FOR PUTTING IT BEFORE. # IF IT MATTERED, WE ASSUME THE LLM WOULD NOT SKIP THE BLOCK else: self.pop_line(self.lines[hunk_ind], hunk_ind) else: hunk_ind += 1 file_ind += 1 # if we have not validated all lines, we have a problem if hunk_ind < len(self.lines) - 1: remaining_lines = "\n".join( f"{line_type}: {line_content}" for line_type, line_content in self.lines[file_ind + 1 :] ) problems.append( f"In {self.hunk_to_string()}:Hunk validation stopped before the lines {remaining_lines} were validated. The diff is incorrect" ) return False return True def validate_and_correct( self, lines_dict: dict, problems: list, ) -> bool: """ Validates and corrects the hunk based on the original lines. This function attempts to validate the hunk by comparing its lines to the original file and making corrections where necessary. It also identifies problems such as non-matching lines or incorrect line types. """ start_true = self.check_start_line(lines_dict) if not start_true: if not self.find_start_line(lines_dict, problems): return False # Now we should be able to validate the hunk line by line and add missing line if not self.validate_lines(lines_dict, problems): return False # Pass the validation return True class Diff: """ Represents a file diff, containing multiple hunks of changes. Attributes: filename_pre (str): The name of the original file. filename_post (str): The name of the edited file. hunks (list): A list of Hunk objects representing the changes in the diff. """ def __init__(self, filename_pre, filename_post) -> None: self.filename_pre = filename_pre self.filename_post = filename_post self.hunks = [] def is_new_file(self) -> bool: """Determines if the diff represents a new file.""" if self.filename_pre == "/dev/null": return True return any(hunk.is_new_file for hunk in self.hunks) def diff_to_string(self) -> str: """Converts the diff to a string representation.""" string = f"--- {self.filename_pre}\n+++ {self.filename_post}\n" for hunk in self.hunks: string += hunk.hunk_to_string() return string.strip() def validate_and_correct(self, lines_dict: dict) -> List[str]: """Validates and corrects each hunk in the diff.""" problems = [] past_hunk = None cut_lines_dict = lines_dict.copy() for hunk in self.hunks: if past_hunk is not None: # make sure to not cut so much that the start_line gets out of range cut_ind = min( past_hunk.start_line_pre_edit + past_hunk.hunk_len_pre_edit, hunk.start_line_pre_edit, ) cut_lines_dict = { key: val for key, val in cut_lines_dict.items() if key >= (cut_ind) } is_valid = hunk.validate_and_correct(cut_lines_dict, problems) if not is_valid and len(problems) > 0: for idx, val in enumerate(problems): print(f"\nInvalid Hunk NO.{idx}---\n{val}\n---") self.hunks.remove(hunk) # now correct the numbers, assuming the start line pre-edit has been fixed hunk.hunk_len_pre_edit = ( hunk.category_counts[RETAIN] + hunk.category_counts[REMOVE] ) hunk.hunk_len_post_edit = ( hunk.category_counts[RETAIN] + hunk.category_counts[ADD] ) if past_hunk is not None: hunk.start_line_post_edit = ( hunk.start_line_pre_edit + past_hunk.hunk_len_post_edit - past_hunk.hunk_len_pre_edit + past_hunk.start_line_post_edit - past_hunk.start_line_pre_edit ) else: hunk.start_line_post_edit = hunk.start_line_pre_edit past_hunk = hunk return problems def is_similar(str1, str2, similarity_threshold=0.9) -> bool: """ Compares two strings for similarity, ignoring spaces and case. Parameters ---------- str1, str2 : str The strings to compare. similarity_threshold: float How similar must the strings be Returns ------- bool True if the strings are similar, False otherwise. """ return count_ratio(str1, str2) >= similarity_threshold def count_ratio(str1, str2) -> float: """ Computes the ratio of common characters to the length of the longer string, ignoring spaces and case. Parameters: - str1, str2 (str): The strings to compare. Returns: - float: The ratio of common characters to the length of the longer string. """ str1, str2 = str1.replace(" ", "").lower(), str2.replace(" ", "").lower() counter1, counter2 = Counter(str1), Counter(str2) intersection = sum((counter1 & counter2).values()) longer_length = max(len(str1), len(str2)) if longer_length == 0: return 1 else: return intersection / longer_length ================================================ FILE: gpt_engineer/core/files_dict.py ================================================ """ FilesDict Module This module provides a FilesDict class which is a dictionary-based container for managing code files. It extends the standard dictionary to enforce string keys and values, representing filenames and their corresponding code content. It also provides methods to format its contents for chat-based interaction with an AI agent and to enforce type checks on keys and values. Classes: FilesDict: A dictionary-based container for managing code files. """ from collections import OrderedDict from pathlib import Path from typing import Union # class Code(MutableMapping[str | Path, str]): # ToDo: implement as mutable mapping, potentially holding a dict instead of being a dict. class FilesDict(dict): """ A dictionary-based container for managing code files. This class extends the standard dictionary to enforce string keys and values, representing filenames and their corresponding code content. It provides methods to format its contents for chat-based interaction with an AI agent and to enforce type checks on keys and values. """ def __setitem__(self, key: Union[str, Path], value: str): """ Set the code content for the given filename, enforcing type checks on the key and value. Overrides the dictionary's __setitem__ to enforce type checks on the key and value. The key must be a string or a Path object, and the value must be a string representing the code content. Parameters ---------- key : Union[str, Path] The filename as a key for the code content. value : str The code content to associate with the filename. Raises ------ TypeError If the key is not a string or Path, or if the value is not a string. """ if not isinstance(key, (str, Path)): raise TypeError("Keys must be strings or Path's") if not isinstance(value, str): raise TypeError("Values must be strings") super().__setitem__(key, value) def to_chat(self): """ Formats the items of the object (assuming file name and content pairs) into a string suitable for chat display. Returns ------- str A string representation of the files. """ chat_str = "" for file_name, file_content in self.items(): lines_dict = file_to_lines_dict(file_content) chat_str += f"File: {file_name}\n" for line_number, line_content in lines_dict.items(): chat_str += f"{line_number} {line_content}\n" chat_str += "\n" return f"```\n{chat_str}```" def to_log(self): """ Formats the items of the object (assuming file name and content pairs) into a string suitable for log display. Returns ------- str A string representation of the files. """ log_str = "" for file_name, file_content in self.items(): log_str += f"File: {file_name}\n" log_str += file_content log_str += "\n" return log_str def file_to_lines_dict(file_content: str) -> dict: """ Converts file content into a dictionary where each line number is a key and the corresponding line content is the value. Parameters ---------- file_name : str The name of the file. file_content : str The content of the file. Returns ------- dict A dictionary with file names as keys and dictionaries (line numbers as keys and line contents as values) as values. """ lines_dict = OrderedDict( { line_number: line_content for line_number, line_content in enumerate(file_content.split("\n"), 1) } ) return lines_dict ================================================ FILE: gpt_engineer/core/git.py ================================================ import shutil import subprocess from pathlib import Path from typing import List from gpt_engineer.core.files_dict import FilesDict def is_git_installed(): return shutil.which("git") is not None def is_git_repo(path: Path): return ( subprocess.run( ["git", "rev-parse", "--is-inside-work-tree"], cwd=path, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ).returncode == 0 ) def init_git_repo(path: Path): subprocess.run(["git", "init"], cwd=path) def has_uncommitted_changes(path: Path): return bool( subprocess.run( ["git", "diff", "--exit-code"], cwd=path, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ).returncode ) def filter_files_with_uncommitted_changes( basepath: Path, files_dict: FilesDict ) -> List[Path]: files_with_diff = ( subprocess.run( ["git", "diff", "--name-only"], cwd=basepath, stdout=subprocess.PIPE ) .stdout.decode() .splitlines() ) return [f for f in files_dict.keys() if f in files_with_diff] def stage_files(path: Path, files: List[str]): subprocess.run(["git", "add", *files], cwd=path) def filter_by_gitignore(path: Path, file_list: List[str]) -> List[str]: out = subprocess.run( ["git", "-C", ".", "check-ignore", "--no-index", "--stdin"], cwd=path, input="\n".join(file_list).encode(), stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) paths = out.stdout.decode().splitlines() # return file_list but filter out the results from git check-ignore return [f for f in file_list if f not in paths] def stage_uncommitted_to_git(path, files_dict, improve_mode): # Check if there's a git repo and verify that there aren't any uncommitted changes if is_git_installed() and not improve_mode: if not is_git_repo(path): print("\nInitializing an empty git repository") init_git_repo(path) if is_git_repo(path): modified_files = filter_files_with_uncommitted_changes(path, files_dict) if modified_files: print( "Staging the following uncommitted files before overwriting: ", ", ".join(modified_files), ) stage_files(path, modified_files) ================================================ FILE: gpt_engineer/core/linting.py ================================================ import black from gpt_engineer.core.files_dict import FilesDict class Linting: def __init__(self): # Dictionary to hold linting methods for different file types self.linters = {".py": self.lint_python} import black def lint_python(self, content, config): """Lint Python files using the `black` library, handling all exceptions silently and logging them. This function attempts to format the code and returns the formatted code if successful. If any error occurs during formatting, it logs the error and returns the original content. """ try: # Try to format the content using black linted_content = black.format_str(content, mode=black.FileMode(**config)) except black.NothingChanged: # If nothing changed, log the info and return the original content print("\nInfo: No changes were made during formatting.\n") linted_content = content except Exception as error: # If any other exception occurs, log the error and return the original content print(f"\nError: Could not format due to {error}\n") linted_content = content return linted_content def lint_files(self, files_dict: FilesDict, config: dict = None) -> FilesDict: """ Lints files based on their extension using registered linting functions. Parameters ---------- files_dict : FilesDict The dictionary of file names to their respective source code content. config : dict, optional A dictionary of configuration options for the linting tools. Returns ------- FilesDict The dictionary of file names to their respective source code content after linting. """ if config is None: config = {} for filename, content in files_dict.items(): extension = filename[ filename.rfind(".") : ].lower() # Ensure case insensitivity if extension in self.linters: original_content = content linted_content = self.linters[extension](content, config) if linted_content != original_content: print(f"Linted {filename}.") else: print(f"No changes made for {filename}.") files_dict[filename] = linted_content else: print(f"No linter registered for {filename}.") return files_dict ================================================ FILE: gpt_engineer/core/preprompts_holder.py ================================================ from pathlib import Path from typing import Dict from gpt_engineer.core.default.disk_memory import DiskMemory class PrepromptsHolder: """ A holder for preprompt texts that are stored on disk. This class provides methods to retrieve preprompt texts from a specified directory. Attributes ---------- preprompts_path : Path The file path to the directory containing preprompt texts. Methods ------- get_preprompts() -> Dict[str, str] Retrieve all preprompt texts from the directory and return them as a dictionary. """ def __init__(self, preprompts_path: Path): self.preprompts_path = preprompts_path def get_preprompts(self) -> Dict[str, str]: preprompts_repo = DiskMemory(self.preprompts_path) return {file_name: preprompts_repo[file_name] for file_name in preprompts_repo} ================================================ FILE: gpt_engineer/core/project_config.py ================================================ """ Functions for reading and writing the `gpt-engineer.toml` configuration file. The `gpt-engineer.toml` file is a TOML file that contains project-specific configuration used by the GPT Engineer CLI and gptengineer.app. """ from dataclasses import asdict, dataclass, field from pathlib import Path import tomlkit default_config_filename = "gpt-engineer.toml" example_config = """ [run] build = "npm run build" test = "npm run test" lint = "quick-lint-js" [paths] base = "./frontend" # base directory to operate in (for monorepos) src = "./src" # source directory (under the base directory) from which context will be retrieved [gptengineer-app] # this namespace is used for gptengineer.app, may be used for internal experiments project_id = "..." # we support multiple OpenAPI schemas, used as context for the LLM openapi = [ { url = "https://api.gptengineer.app/openapi.json" }, { url = "https://some-color-translating-api/openapi.json" }, ] """ @dataclass class _PathsConfig: base: str | None = None src: str | None = None @dataclass class _RunConfig: build: str | None = None test: str | None = None lint: str | None = None format: str | None = None @dataclass class _OpenApiConfig: url: str @dataclass class _GptEngineerAppConfig: project_id: str openapi: list[_OpenApiConfig] | None = None def filter_none(d: dict) -> dict: # Drop None values and empty dictionaries from a dictionary return { k: v for k, v in ( (k, filter_none(v) if isinstance(v, dict) else v) for k, v in d.items() if v is not None ) if not (isinstance(v, dict) and not v) # Check for non-empty after filtering } @dataclass class Config: """Configuration for the GPT Engineer CLI and gptengineer.app via `gpt-engineer.toml`.""" paths: _PathsConfig = field(default_factory=_PathsConfig) run: _RunConfig = field(default_factory=_RunConfig) gptengineer_app: _GptEngineerAppConfig | None = None @classmethod def from_toml(cls, config_file: Path | str): if isinstance(config_file, str): config_file = Path(config_file) config_dict = read_config(config_file) return cls.from_dict(config_dict) @classmethod def from_dict(cls, config_dict: dict): run = _RunConfig(**config_dict.get("run", {})) paths = _PathsConfig(**config_dict.get("paths", {})) # load optional gptengineer-app section gptengineer_app_dict = config_dict.get("gptengineer-app", {}) gptengineer_app = None if gptengineer_app_dict: assert ( "project_id" in gptengineer_app_dict ), "project_id is required in gptengineer-app section" gptengineer_app = _GptEngineerAppConfig( # required if gptengineer-app section is present project_id=gptengineer_app_dict["project_id"], openapi=[ _OpenApiConfig(**openapi) for openapi in gptengineer_app_dict.get("openapi", []) ] or None, ) return cls(paths=paths, run=run, gptengineer_app=gptengineer_app) def to_dict(self) -> dict: d = asdict(self) d["gptengineer-app"] = d.pop("gptengineer_app", None) # Drop None values and empty dictionaries # Needed because tomlkit.dumps() doesn't handle None values, # and we don't want to write empty sections. d = filter_none(d) return d def to_toml(self, config_file: Path | str, save=True) -> str: """Write the configuration to a TOML file.""" if isinstance(config_file, str): config_file = Path(config_file) # Load the TOMLDocument and overwrite it with the new values config = read_config(config_file) default_config = Config().to_dict() for k, v in self.to_dict().items(): # only write values that are already explicitly set, or that differ from defaults if k in config or v != default_config[k]: if isinstance(v, dict): config[k] = { k2: v2 for k2, v2 in v.items() if ( k2 in config[k] or default_config.get(k) is None or v2 != default_config[k].get(k2) ) } else: config[k] = v toml_str = tomlkit.dumps(config) if save: with open(config_file, "w") as f: f.write(toml_str) return toml_str def read_config(config_file: Path) -> tomlkit.TOMLDocument: """Read the configuration file""" assert config_file.exists(), f"Config file {config_file} does not exist" with open(config_file, "r") as f: return tomlkit.load(f) ================================================ FILE: gpt_engineer/core/prompt.py ================================================ import json from typing import Dict, Optional class Prompt: def __init__( self, text: str, image_urls: Optional[Dict[str, str]] = None, entrypoint_prompt: str = "", ): self.text = text self.image_urls = image_urls self.entrypoint_prompt = entrypoint_prompt def __repr__(self): return f"Prompt(text={self.text!r}, image_urls={self.image_urls!r})" def to_langchain_content(self): content = [{"type": "text", "text": f"Request: {self.text}"}] if self.image_urls: for name, url in self.image_urls.items(): image_content = { "type": "image_url", "image_url": { "url": url, "detail": "low", }, } content.append(image_content) return content def to_dict(self): return { "text": self.text, "image_urls": self.image_urls, "entrypoint_prompt": self.entrypoint_prompt, } def to_json(self): return json.dumps(self.to_dict()) ================================================ FILE: gpt_engineer/core/token_usage.py ================================================ import base64 import io import logging import math from dataclasses import dataclass from typing import List, Union import tiktoken from langchain.schema import AIMessage, HumanMessage, SystemMessage from PIL import Image # workaround for function moved in: # https://github.com/langchain-ai/langchain/blob/535db72607c4ae308566ede4af65295967bb33a8/libs/community/langchain_community/callbacks/openai_info.py try: from langchain.callbacks.openai_info import ( get_openai_token_cost_for_model, # fmt: skip ) except ImportError: from langchain_community.callbacks.openai_info import ( get_openai_token_cost_for_model, # fmt: skip ) Message = Union[AIMessage, HumanMessage, SystemMessage] logger = logging.getLogger(__name__) @dataclass class TokenUsage: """ Dataclass representing token usage statistics for a conversation step. Attributes ---------- step_name : str The name of the conversation step. in_step_prompt_tokens : int The number of prompt tokens used in the step. in_step_completion_tokens : int The number of completion tokens used in the step. in_step_total_tokens : int The total number of tokens used in the step. total_prompt_tokens : int The cumulative number of prompt tokens used up to this step. total_completion_tokens : int The cumulative number of completion tokens used up to this step. total_tokens : int The cumulative total number of tokens used up to this step. """ """ Represents token usage statistics for a conversation step. """ step_name: str in_step_prompt_tokens: int in_step_completion_tokens: int in_step_total_tokens: int total_prompt_tokens: int total_completion_tokens: int total_tokens: int class Tokenizer: """ Tokenizer for counting tokens in text. """ def __init__(self, model_name): self.model_name = model_name self._tiktoken_tokenizer = ( tiktoken.encoding_for_model(model_name) if "gpt-4" in model_name or "gpt-3.5" in model_name else tiktoken.get_encoding("cl100k_base") ) def num_tokens(self, txt: str) -> int: """ Get the number of tokens in a text. Parameters ---------- txt : str The text to count the tokens in. Returns ------- int The number of tokens in the text. """ return len(self._tiktoken_tokenizer.encode(txt)) def num_tokens_for_base64_image( self, image_base64: str, detail: str = "high" ) -> int: """ Calculate the token size for a base64 encoded image based on OpenAI's token calculation rules. Parameters: - image_base64 (str): The base64 encoded string of the image. - detail (str): The detail level of the image, 'low' or 'high'. Returns: - int: The token size of the image. """ if detail == "low": return 85 # Fixed cost for low detail images # Decode image from base64 image_data = base64.b64decode(image_base64) # Convert byte data to image for size extraction image = Image.open(io.BytesIO(image_data)) # Calculate the initial scale to fit within 2048 square while maintaining aspect ratio max_dimension = max(image.size) scale_factor = min(2048 / max_dimension, 1) # Ensure we don't scale up new_width = int(image.size[0] * scale_factor) new_height = int(image.size[1] * scale_factor) # Scale such that the shortest side is 768px shortest_side = min(new_width, new_height) if shortest_side > 768: resize_factor = 768 / shortest_side new_width = int(new_width * resize_factor) new_height = int(new_height * resize_factor) # Calculate the number of 512px tiles needed width_tiles = math.ceil(new_width / 512) height_tiles = math.ceil(new_height / 512) total_tiles = width_tiles * height_tiles # Each tile costs 170 tokens, plus a base cost of 85 tokens for high detail token_cost = total_tiles * 170 + 85 return token_cost def num_tokens_from_messages(self, messages: List[Message]) -> int: """ Get the total number of tokens used by a list of messages, accounting for text and base64 encoded images. Parameters ---------- messages : List[Message] The list of messages to count the tokens in. Returns ------- int The total number of tokens used by the messages. """ n_tokens = 0 for message in messages: n_tokens += 4 # Account for message framing tokens if isinstance(message.content, str): # Content is a simple string n_tokens += self.num_tokens(message.content) elif isinstance(message.content, list): # Content is a list, potentially mixed with text and images for item in message.content: if item.get("type") == "text": n_tokens += self.num_tokens(item["text"]) elif item.get("type") == "image_url": image_detail = item["image_url"].get("detail", "high") image_base64 = item["image_url"].get("url") n_tokens += self.num_tokens_for_base64_image( image_base64, detail=image_detail ) n_tokens += 2 # Account for assistant's reply framing tokens return n_tokens class TokenUsageLog: """ Represents a log of token usage statistics for a conversation. """ def __init__(self, model_name): self.model_name = model_name self._cumulative_prompt_tokens = 0 self._cumulative_completion_tokens = 0 self._cumulative_total_tokens = 0 self._log = [] self._tokenizer = Tokenizer(model_name) def update_log(self, messages: List[Message], answer: str, step_name: str) -> None: """ Update the token usage log with the number of tokens used in the current step. Parameters ---------- messages : List[Message] The list of messages in the conversation. answer : str The answer from the AI. step_name : str The name of the step. """ prompt_tokens = self._tokenizer.num_tokens_from_messages(messages) completion_tokens = self._tokenizer.num_tokens(answer) total_tokens = prompt_tokens + completion_tokens self._cumulative_prompt_tokens += prompt_tokens self._cumulative_completion_tokens += completion_tokens self._cumulative_total_tokens += total_tokens self._log.append( TokenUsage( step_name=step_name, in_step_prompt_tokens=prompt_tokens, in_step_completion_tokens=completion_tokens, in_step_total_tokens=total_tokens, total_prompt_tokens=self._cumulative_prompt_tokens, total_completion_tokens=self._cumulative_completion_tokens, total_tokens=self._cumulative_total_tokens, ) ) def log(self) -> List[TokenUsage]: """ Get the token usage log. Returns ------- List[TokenUsage] A log of token usage details per step in the conversation. """ return self._log def format_log(self) -> str: """ Format the token usage log as a CSV string. Returns ------- str The token usage log formatted as a CSV string. """ result = "step_name,prompt_tokens_in_step,completion_tokens_in_step,total_tokens_in_step,total_prompt_tokens,total_completion_tokens,total_tokens\n" for log in self._log: result += f"{log.step_name},{log.in_step_prompt_tokens},{log.in_step_completion_tokens},{log.in_step_total_tokens},{log.total_prompt_tokens},{log.total_completion_tokens},{log.total_tokens}\n" return result def is_openai_model(self) -> bool: """ Check if the model is an OpenAI model. Returns ------- bool True if the model is an OpenAI model, False otherwise. """ return "gpt" in self.model_name.lower() def total_tokens(self) -> int: """ Return the total number of tokens used in the conversation. Returns ------- int The total number of tokens used in the conversation. """ return self._cumulative_total_tokens def usage_cost(self) -> float | None: """ Return the total cost in USD of the API usage. Returns ------- float Cost in USD. """ if not self.is_openai_model(): return None try: result = 0 for log in self.log(): result += get_openai_token_cost_for_model( self.model_name, log.total_prompt_tokens, is_completion=False ) result += get_openai_token_cost_for_model( self.model_name, log.total_completion_tokens, is_completion=True ) return result except Exception as e: print(f"Error calculating usage cost: {e}") return None ================================================ FILE: gpt_engineer/core/version_manager.py ================================================ """ Version Manager Module This module provides an abstract base class for a version manager that handles the creation of snapshots for code. Implementations of this class are expected to provide methods to create a snapshot of the given code and return a reference to it. """ from abc import ABC, abstractmethod from pathlib import Path from typing import Union from gpt_engineer.core.files_dict import FilesDict class BaseVersionManager(ABC): """ Abstract base class for a version manager. Defines the interface for version managers that handle the creation of snapshots for code. Implementations of this class are expected to provide methods to create a snapshot of the given code and return a reference to it. """ @abstractmethod def __init__(self, path: Union[str, Path]): pass @abstractmethod def snapshot(self, files_dict: FilesDict) -> str: pass ================================================ FILE: gpt_engineer/preprompts/clarify ================================================ Given some instructions, determine if anything needs to be clarified, do not carry them out. You can make reasonable assumptions, but if you are unsure, ask a single clarification question. Otherwise state: "Nothing to clarify" ================================================ FILE: gpt_engineer/preprompts/entrypoint ================================================ You will get information about a codebase that is currently on disk in the current folder. The user will ask you to write a script that runs the code in a specific way. You will answer with code blocks that include all the necessary terminal commands. Do not install globally. Do not use sudo. Do not explain the code, just give the commands. Do not use placeholders, use example values (like . for a folder argument) if necessary. ================================================ FILE: gpt_engineer/preprompts/file_format ================================================ You will output the content of each file necessary to achieve the goal, including ALL code. Represent files like so: FILENAME ``` CODE ``` The following tokens must be replaced like so: FILENAME is the lowercase combined path and file name including the file extension CODE is the code in the file Example representation of a file: src/hello_world.py ``` print("Hello World") ``` Do not comment on what every file does. Please note that the code should be fully functional. No placeholders. ================================================ FILE: gpt_engineer/preprompts/file_format_diff ================================================ You will output the content of each file necessary to achieve the goal, including ALL code. Output requested code changes and new code in the unified "git diff" syntax. Example: ```diff --- example.txt +++ example.txt @@ -6,3 +6,4 @@ line content A line content B + new line added - original line X + modified line X with changes @@ -26,4 +27,5 @@ condition check: - action for condition A + if certain condition is met: + alternative action for condition A another condition check: - action for condition B + modified action for condition B ``` Example of a git diff creating a new file: ```diff --- /dev/null +++ new_file.txt @@ -0,0 +1,3 @@ +First example line + +Last example line ``` RULES: -A program will apply the diffs you generate exactly to the code, so diffs must be precise and unambiguous! -Every diff must be fenced with triple backtick ```. -The file names at the beginning of a diff, (lines starting with --- and +++) is the relative path to the file before and after the diff. -LINES TO BE REMOVED (starting with single -) AND LINES TO BE RETAIN (no starting symbol) HAVE TO REPLICATE THE DIFFED HUNK OF THE CODE EXACTLY LINE BY LINE. KEEP THE NUMBER OF RETAIN LINES SMALL IF POSSIBLE. -EACH LINE IN THE SOURCE FILES STARTS WITH A LINE NUMBER, WHICH IS NOT PART OF THE SOURCE CODE. NEVER TRANSFER THESE LINE NUMBERS TO THE DIFF HUNKS. -AVOID STARTING A HUNK WITH AN EMPTY LINE. -ENSURE ALL CHANGES ARE PROVIDED IN A SINGLE DIFF CHUNK PER FILE TO PREVENT MULTIPLE DIFFS ON THE SAME FILE. ================================================ FILE: gpt_engineer/preprompts/file_format_fix ================================================ Please fix any errors in the code above. You will output the content of each new or changed. Represent files like so: FILENAME ``` CODE ``` The following tokens must be replaced like so: FILENAME is the lowercase combined path and file name including the file extension CODE is the code in the file Example representation of a file: src/hello_world.py ``` print("Hello World") ``` Do not comment on what every file does. Please note that the code should be fully functional. No placeholders. ================================================ FILE: gpt_engineer/preprompts/generate ================================================ Think step by step and reason yourself to the correct decisions to make sure we get it right. First lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose. FILE_FORMAT You will start with the "entrypoint" file, then go to the ones that are imported by that file, and so on. Please note that the code should be fully functional. No placeholders. Follow a language and framework appropriate best practice file naming convention. Make sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other. Ensure to implement all code, if you are unsure, write a plausible implementation. Include module dependency or package manager dependency definition file. Before you finish, double check that all parts of the architecture is present in the files. When you are done, write finish with "this concludes a fully working implementation". ================================================ FILE: gpt_engineer/preprompts/improve ================================================ Think step by step and reason yourself to the correct decisions to make sure we get it right. Make changes to existing code and implement new code in the unified git diff syntax. When implementing new code, First lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose. FILE_FORMAT As far as compatible with the user request, start with the "entrypoint" file, then go to the ones that are imported by that file, and so on. Please note that the code should be fully functional. No placeholders. Follow a language and framework appropriate best practice file naming convention. Make sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other. Ensure to implement all code, if you are unsure, write a plausible implementation. Include module dependency or package manager dependency definition file. Before you finish, double check that all parts of the architecture is present in the files. When you are done, write finish with "this concludes a fully working implementation". ================================================ FILE: gpt_engineer/preprompts/philosophy ================================================ Almost always put different classes in different files. Always use the programming language the user asks for. For Python, you always create an appropriate requirements.txt file. For NodeJS, you always create an appropriate package.json file. Always add a comment briefly describing the purpose of the function definition. Add comments explaining very complex bits of logic. Always follow the best practices for the requested languages for folder/file structure and how to package the project. Python toolbelt preferences: - pytest - dataclasses ================================================ FILE: gpt_engineer/preprompts/roadmap ================================================ You will get instructions for code to write. You will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code. ================================================ FILE: gpt_engineer/tools/__init__.py ================================================ ================================================ FILE: gpt_engineer/tools/custom_steps.py ================================================ from platform import platform from sys import version_info from typing import List, Union from langchain.schema import AIMessage, HumanMessage, SystemMessage from gpt_engineer.core.ai import AI from gpt_engineer.core.base_execution_env import BaseExecutionEnv from gpt_engineer.core.base_memory import BaseMemory from gpt_engineer.core.chat_to_files import chat_to_files_dict from gpt_engineer.core.default.paths import CODE_GEN_LOG_FILE, ENTRYPOINT_FILE from gpt_engineer.core.default.steps import curr_fn, improve_fn, setup_sys_prompt from gpt_engineer.core.files_dict import FilesDict from gpt_engineer.core.preprompts_holder import PrepromptsHolder from gpt_engineer.core.prompt import Prompt # Type hint for chat messages Message = Union[AIMessage, HumanMessage, SystemMessage] MAX_SELF_HEAL_ATTEMPTS = 10 def get_platform_info() -> str: """ Returns a string containing the OS and Python version information. This function is used for self-healing by providing information about the current operating system and Python version. It assumes that the Python version in the virtual environment is the one being used. Returns: str: A string containing the OS and Python version information. """ v = version_info a = f"Python Version: {v.major}.{v.minor}.{v.micro}" b = f"\nOS: {platform()}\n" return a + b def self_heal( ai: AI, execution_env: BaseExecutionEnv, files_dict: FilesDict, prompt: Prompt = None, preprompts_holder: PrepromptsHolder = None, memory: BaseMemory = None, diff_timeout=3, ) -> FilesDict: """ Attempts to execute the code from the entrypoint and if it fails, sends the error output back to the AI with instructions to fix. Parameters ---------- ai : AI An instance of the AI model. execution_env : BaseExecutionEnv The execution environment where the code is run. files_dict : FilesDict A dictionary of file names to their contents. preprompts_holder : PrepromptsHolder, optional A holder for preprompt messages. Returns ------- FilesDict The updated files dictionary after self-healing attempts. Raises ------ FileNotFoundError If the required entrypoint file does not exist in the code. AssertionError If the preprompts_holder is None. Notes ----- This code will make `MAX_SELF_HEAL_ATTEMPTS` to try and fix the code before giving up. This makes the assuption that the previous step was `gen_entrypoint`, this code could work with `simple_gen`, or `gen_clarified_code` as well. """ # step 1. execute the entrypoint # log_path = dbs.workspace.path / "log.txt" if ENTRYPOINT_FILE not in files_dict: raise FileNotFoundError( "The required entrypoint " + ENTRYPOINT_FILE + " does not exist in the code." ) attempts = 0 if preprompts_holder is None: raise AssertionError("Prepromptsholder required for self-heal") while attempts < MAX_SELF_HEAL_ATTEMPTS: attempts += 1 timed_out = False # Start the process execution_env.upload(files_dict) p = execution_env.popen(files_dict[ENTRYPOINT_FILE]) # Wait for the process to complete and get output stdout_full, stderr_full = p.communicate() if (p.returncode != 0 and p.returncode != 2) and not timed_out: print("run.sh failed. The log is:") print(stdout_full.decode("utf-8")) print(stderr_full.decode("utf-8")) new_prompt = Prompt( f"A program with this specification was requested:\n{prompt}\n, but running it produced the following output:\n{stdout_full}\n and the following errors:\n{stderr_full}. Please change it so that it fulfills the requirements." ) files_dict = improve_fn( ai, new_prompt, files_dict, memory, preprompts_holder, diff_timeout ) else: break return files_dict def clarified_gen( ai: AI, prompt: Prompt, memory: BaseMemory, preprompts_holder: PrepromptsHolder ) -> FilesDict: """ Generates code based on clarifications obtained from the user and saves it to a specified workspace. Parameters ---------- ai : AI An instance of the AI model, responsible for processing and generating the code. prompt : str The user's clarification prompt. memory : BaseMemory The memory instance where the generated code log is saved. preprompts_holder : PrepromptsHolder A holder for preprompt messages. Returns ------- FilesDict A dictionary of file names to their contents generated by the AI. """ preprompts = preprompts_holder.get_preprompts() messages: List[Message] = [SystemMessage(content=preprompts["clarify"])] user_input = prompt.text # clarify does not work with vision right now while True: messages = ai.next(messages, user_input, step_name=curr_fn()) msg = messages[-1].content.strip() if "nothing to clarify" in msg.lower(): break if msg.lower().startswith("no"): print("Nothing to clarify.") break print('(answer in text, or "c" to move on)\n') user_input = input("") print() if not user_input or user_input == "c": print("(letting gpt-engineer make its own assumptions)") print() messages = ai.next( messages, "Make your own assumptions and state them explicitly before starting", step_name=curr_fn(), ) print() user_input += """ \n\n Is anything else unclear? If yes, ask another question.\n Otherwise state: "Nothing to clarify" """ print() messages = [ SystemMessage(content=setup_sys_prompt(preprompts)), ] + messages[ 1: ] # skip the first clarify message, which was the original clarify priming prompt messages = ai.next( messages, preprompts["generate"].replace("FILE_FORMAT", preprompts["file_format"]), step_name=curr_fn(), ) print() chat = messages[-1].content.strip() memory.log(CODE_GEN_LOG_FILE, "\n\n".join(x.pretty_repr() for x in messages)) files_dict = chat_to_files_dict(chat) return files_dict def lite_gen( ai: AI, prompt: Prompt, memory: BaseMemory, preprompts_holder: PrepromptsHolder ) -> FilesDict: """ Executes the AI model using the main prompt and saves the generated results to the specified workspace. Parameters ---------- ai : AI An instance of the AI model. prompt : str The main prompt to feed to the AI model. memory : BaseMemory The memory instance where the generated code log is saved. preprompts_holder : PrepromptsHolder A holder for preprompt messages. Returns ------- FilesDict A dictionary of file names to their contents generated by the AI. Notes ----- The function assumes the `ai.start` method and the `to_files` utility to be correctly set up and functional. Ensure these prerequisites before invoking `lite_gen`. """ preprompts = preprompts_holder.get_preprompts() messages = ai.start( prompt.to_langchain_content(), preprompts["file_format"], step_name=curr_fn() ) chat = messages[-1].content.strip() memory.log(CODE_GEN_LOG_FILE, "\n\n".join(x.pretty_repr() for x in messages)) files_dict = chat_to_files_dict(chat) return files_dict ================================================ FILE: gpt_engineer/tools/supported_languages.py ================================================ """ This module defines the supported programming languages for document chunking. Variables: SUPPORTED_LANGUAGES (list): A list of dictionaries defining supported languages. """ SUPPORTED_LANGUAGES = [ {"name": "Python", "extensions": [".py"], "tree_sitter_name": "python"}, { "name": "JavaScript", "extensions": [".js", ".mjs"], "tree_sitter_name": "javascript", }, {"name": "HTML", "extensions": [".html", ".htm"], "tree_sitter_name": "html"}, {"name": "CSS", "extensions": [".css"], "tree_sitter_name": "css"}, {"name": "Java", "extensions": [".java"], "tree_sitter_name": "java"}, {"name": "C#", "extensions": [".cs"], "tree_sitter_name": "c_sharp"}, { "name": "TypeScript", "extensions": [".ts", ".tsx"], "tree_sitter_name": "typescript", }, {"name": "Ruby", "extensions": [".rb", ".erb"], "tree_sitter_name": "ruby"}, { "name": "PHP", "extensions": [ ".php", ".phtml", ".php3", ".php4", ".php5", ".php7", ".phps", ".php-s", ".pht", ".phar", ], "tree_sitter_name": "php", }, {"name": "Go", "extensions": [".go"], "tree_sitter_name": "go"}, {"name": "Kotlin", "extensions": [".kt", ".kts"], "tree_sitter_name": "kotlin"}, {"name": "Rust", "extensions": [".rs"], "tree_sitter_name": "rust"}, { "name": "C++", "extensions": [".cpp", ".cc", ".cxx", ".h", ".hpp", ".hxx"], "tree_sitter_name": "cpp", }, {"name": "C", "extensions": [".c", ".h"], "tree_sitter_name": "c"}, {"name": "Markdown", "extensions": [".md"], "tree_sitter_name": "md"}, {"name": "Arduino C", "extensions": [".ino"], "tree_sitter_name": "ino"} # ---- the following are not supported by the current code chunker implementation ---- # { # "name": "Swift", # "extensions": [".swift"], # "tree_sitter_name": "swift" # }, ] ================================================ FILE: projects/example-improve/README.md ================================================ To implement the game Snake in Python using the Model-View-Controller (MVC) design pattern, we will need several classes and files. The game will be controlled using the keyboard. Here are the core classes and their purposes: 1. `Game`: This is the main class that will control the game flow. It will be responsible for starting the game, handling user input, and updating the game state. 2. `Snake`: This class will represent the snake in the game. It will have methods to move the snake, grow the snake, and check if the snake has collided with itself. 3. `Food`: This class will represent the food in the game. It will have methods to place the food at a random location on the game board. 4. `Board`: This class will represent the game board. It will have methods to draw the board, the snake, and the food. 5. `Controller`: This class will handle user input. It will have methods to listen for keyboard events and update the direction of the snake accordingly. Now, let's start with the entry point file, `main.py`, and then go to the ones that are imported by that file. src/main.py ================================================ FILE: projects/example-improve/controller.py ================================================ import keyboard class Controller: def __init__(self, game, view): self.game = game 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 elif keyboard.is_pressed("down"): self.game.move("up") elif keyboard.is_pressed("left"): self.game.move("right") elif keyboard.is_pressed("right"): self.game.move("left") ================================================ FILE: projects/example-improve/main.py ================================================ from controller import Controller from model import Game from view import View def main(): game = Game() view = View(game) controller = Controller(game, view) while game.is_running: controller.handle_input() game.update() view.render() if __name__ == "__main__": main() ================================================ FILE: projects/example-improve/model.py ================================================ import random from dataclasses import dataclass @dataclass class Point: x: int y: int class Game: def __init__(self): self.snake = [Point(5, 5)] self.food = self.generate_food() self.is_running = True def generate_food(self): return Point(random.randint(0, 10), random.randint(0, 10)) def update(self): # Move the snake self.snake.move() # Check for collision with food 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): self.is_running = False ================================================ FILE: projects/example-improve/prompt ================================================ If up is pressed, the snake should turn down and after one step to the right. If down is pressed it should go up. Also, make the snake go left when right is pressed and right when left is pressed. ================================================ FILE: projects/example-improve/requirements.txt ================================================ keyboard==0.13.5 ================================================ FILE: projects/example-improve/run.sh ================================================ # a) Install dependencies python3 -m venv venv source venv/bin/activate pip install -r requirements.txt # b) Run all necessary parts of the codebase python main.py ================================================ FILE: projects/example-improve/view.py ================================================ 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="") else: print(".", end="") print() print() ================================================ FILE: projects/example-vision/navigation.html ================================================ ================================================ FILE: projects/example-vision/prompt ================================================ Alter the nav so it looks like the ux diagram provided ================================================ FILE: pyproject.toml ================================================ [tool.poetry] name = "gpt-engineer" version = "0.3.1" description = "Specify what you want it to build, the AI asks for clarification, and then builds it." authors = ["Anton Osika "] license = "MIT" readme = "README.md" homepage = "https://github.com/gpt-engineer-org/gpt-engineer" repository = "https://github.com/gpt-engineer-org/gpt-engineer" documentation = "https://gpt-engineer.readthedocs.io/en/latest/" classifiers = [ "Development Status :: 4 - Beta", "Topic :: Scientific/Engineering :: Artificial Intelligence", ] [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" [tool.poetry.dependencies] python = ">=3.10,<3.13" openai = "^1.0" termcolor = "2.3.0" typer = ">=0.3.2" rudder-sdk-python = ">=2.0.2" dataclasses-json = "0.5.7" tiktoken = ">=0.0.4" tabulate = "0.9.0" python-dotenv = ">=0.21.0" langchain = ">=0.1.2" langchain_openai = "*" toml = ">=0.10.2" tomlkit = "^0.12.4" pyperclip = "^1.8.2" langchain-anthropic = "^0.1.1" regex = "^2023.12.25" pillow = "^10.2.0" datasets = "^2.17.1" black = "23.3.0" langchain-community = "^0.2.0" [tool.poetry.group.dev.dependencies] pytest = ">=7.3.1" pytest-cov = "^4.1.0" mypy = "1.3.0" ruff = ">=0.0.272" pre-commit = "3.3.3" tox = ">=3.0.0" [tool.poetry.group.docs.dependencies] autodoc_pydantic = ">=1.8.0" myst_parser = ">=0.18.1" nbsphinx = ">=0.8.9" sphinx = ">=5.0.0" sphinx-autobuild = ">=2021.3.14" sphinx_book_theme = ">=0.3.3" sphinx_rtd_theme = ">=1.0.0" sphinx-typlog-theme = ">=0.8.0" toml = ">=0.10.2" myst-nb = ">=0.17.1" linkchecker = ">=10.2.1" sphinx-copybutton = ">=0.5.1" markdown-include = ">=0.6.0" sphinx_copybutton = ">=0.5.2" [tool.poetry.scripts] gpt-engineer = 'gpt_engineer.applications.cli.main:app' ge = 'gpt_engineer.applications.cli.main:app' gpte = 'gpt_engineer.applications.cli.main:app' bench = 'gpt_engineer.benchmark.__main__:app' gpte_test_application = 'tests.caching_main:app' [tool.poetry.extras] test = ["pytest", "pytest-cov"] doc = [ "autodoc_pydantic", "myst_parser", "nbsphinx", "sphinx", "sphinx-autobuild", "sphinx_book_theme", "sphinx_rtd_theme", "sphinx-typlog-theme", "myst-nb", "linkchecker", "sphinx-copybutton", "markdown-include", "sphinx_copybutton", ] [tool.ruff] select = ["F", "E", "W", "I001"] show-fixes = false target-version = "py310" task-tags = ["TODO", "FIXME"] extend-ignore = ["E501", "E722"] [tool.black] target-version = ["py310"] [tool.ruff.isort] known-first-party = [] known-third-party = [] section-order = [ "future", "standard-library", "third-party", "first-party", "local-folder", ] combine-as-imports = true split-on-trailing-comma = false lines-between-types = 1 [tool.pytest.ini_options] markers = [ "requires_key: marks tests as requiring access to a valid OPENAI_API_KEY (deselect with '-m \"not requires_key\"')", ] ================================================ FILE: scripts/clean_benchmarks.py ================================================ """ This module provides functionality to clean up benchmark directories by removing all files and folders except for 'prompt' and 'main_prompt'. """ # list all folders in benchmark folder # for each folder, run the benchmark import os import shutil from pathlib import Path from typer import run def main(): """ Main function that iterates through all directories in the 'benchmark' folder and cleans them by removing all files and directories except for 'prompt' and 'main_prompt'. """ benchmarks = Path("benchmark") for benchmark in benchmarks.iterdir(): if benchmark.is_dir(): print(f"Cleaning {benchmark}") for path in benchmark.iterdir(): if path.name in ["prompt", "main_prompt"]: continue # Get filename of Path object if path.is_dir(): # delete the entire directory shutil.rmtree(path) else: # delete the file os.remove(path) if __name__ == "__main__": run(main) ================================================ FILE: scripts/legacy_benchmark.py ================================================ """ This module provides functionality to run benchmarks on different folders within the 'benchmark' directory, wait for their completion, and generate a report. """ # list all folders in benchmark folder # for each folder, run the benchmark import contextlib import json import os import subprocess from datetime import datetime from itertools import islice from pathlib import Path from typing import Iterable, Union from tabulate import tabulate from typer import run def main( n_benchmarks: Union[int, None] = None, ): """ Main function that runs benchmarks on folders within the 'benchmark' directory. Parameters ---------- n_benchmarks : Union[int, None], optional The number of benchmarks to run. If None, all benchmarks are run. """ path = Path("benchmark") folders: Iterable[Path] = path.iterdir() if n_benchmarks: folders = islice(folders, n_benchmarks) benchmarks = [] results = [] for bench_folder in folders: if os.path.isdir(bench_folder): print(f"Running benchmark for {bench_folder}") log_path = bench_folder / "log.txt" log_file = open(log_path, "w") process = subprocess.Popen( [ "python", "-u", # Unbuffered output "-m", "gpt_engineer.cli.main", bench_folder, "--steps", "benchmark", ], stdout=log_file, stderr=log_file, bufsize=0, ) benchmarks.append(bench_folder) results.append((process, log_file)) print("You can stream the log file by running:") print(f"tail -f {log_path}") print() for bench_folder, (process, file) in zip(benchmarks, results): process.wait() file.close() print("process", bench_folder.name, "finished with code", process.returncode) print("Running it. Original benchmark prompt:") print() with open(bench_folder / "prompt") as f: print(f.read()) print() with contextlib.suppress(KeyboardInterrupt): subprocess.run( [ "python", "-m", "gpt_engineer.cli.main", bench_folder, "--steps", "evaluate", ], ) generate_report(benchmarks, path) def generate_report(benchmarks, benchmark_path): """ Generates a report of the benchmark results and optionally appends it to a markdown file. Parameters ---------- benchmarks : list A list of benchmark folder paths that have been processed. benchmark_path : Path The path to the benchmark directory. """ headers = ["Benchmark", "Ran", "Works", "Perfect", "Notes"] rows = [] for bench_folder in benchmarks: memory = bench_folder / ".gpteng" / "memory" with open(memory / "review") as f: review = json.loads(f.read()) rows.append( [ bench_folder.name, to_emoji(review.get("ran", None)), to_emoji(review.get("works", None)), to_emoji(review.get("perfect", None)), review.get("comments", None), ] ) table: str = tabulate(rows, headers, tablefmt="pipe") print("\nBenchmark report:\n") print(table) print() append_to_results = ask_yes_no("Append report to the results file?") if append_to_results: results_path = benchmark_path / "RESULTS.md" current_date = datetime.now().strftime("%Y-%m-%d") insert_markdown_section(results_path, current_date, table, 2) def to_emoji(value: bool) -> str: """ Converts a boolean value to its corresponding emoji representation. Parameters ---------- value : bool The boolean value to convert. Returns ------- str An emoji string representing the boolean value. """ return "\U00002705" if value else "\U0000274C" def insert_markdown_section(file_path, section_title, section_text, level): """ Inserts a new section into a markdown file at the specified level. Parameters ---------- file_path : Path The path to the markdown file. section_title : str The title of the section to insert. section_text : str The text content of the section to insert. level : int The header level of the section. """ with open(file_path, "r") as file: lines = file.readlines() header_prefix = "#" * level new_section = f"{header_prefix} {section_title}\n\n{section_text}\n\n" # Find the first section with the specified level line_number = -1 for i, line in enumerate(lines): if line.startswith(header_prefix): line_number = i break if line_number != -1: lines.insert(line_number, new_section) else: print( f"Markdown file was of unexpected format. No section of level {level} found. " "Did not write results." ) return # Write the file with open(file_path, "w") as file: file.writelines(lines) def ask_yes_no(question: str) -> bool: """ Asks a yes/no question and returns the response as a boolean value. Parameters ---------- question : str The yes/no question to ask. Returns ------- bool True if the answer is 'yes', False if 'no'. """ while True: response = input(question + " (y/n): ").lower().strip() if response == "y": return True elif response == "n": return False else: print("Please enter either 'y' or 'n'.") if __name__ == "__main__": run(main) ================================================ FILE: scripts/print_chat.py ================================================ """ This module provides functionality to print a conversation with messages colored according to the role of the speaker. """ import json import typer from termcolor import colored app = typer.Typer() def pretty_print_conversation(messages): """ Prints a conversation with messages formatted and colored by role. Parameters ---------- messages : list A list of message dictionaries, each containing 'role', 'name', and 'content' keys. """ role_to_color = { "system": "red", "user": "green", "assistant": "blue", "function": "magenta", } formatted_messages = [] for message in messages: if message["role"] == "function": formatted_messages.append( f"function ({message['name']}): {message['content']}\n" ) else: assistant_content = ( message["function_call"] if message.get("function_call") else message["content"] ) role_to_message = { "system": f"system: {message['content']}\n", "user": f"user: {message['content']}\n", "assistant": f"assistant: {assistant_content}\n", } formatted_messages.append(role_to_message[message["role"]]) for formatted_message in formatted_messages: role = messages[formatted_messages.index(formatted_message)]["role"] color = role_to_color[role] print(colored(formatted_message, color)) @app.command() def main( messages_path: str, ): """ Main function that loads messages from a JSON file and prints them using pretty formatting. Parameters ---------- messages_path : str The file path to the JSON file containing the messages. """ with open(messages_path) as f: messages = json.load(f) pretty_print_conversation(messages) if __name__ == "__main__": app() ================================================ FILE: scripts/test_api.py ================================================ """This is just a demo to test api.py.""" from time import sleep import requests def post_data(url, extra_arguments): """ Make an HTTP POST request with extra_arguments as data. Parameters ---------- url : str The URL to which the POST request should be sent. extra_arguments : dict A dictionary of data that needs to be sent in the POST request. Returns ------- response The response from the server. """ response = requests.post(url, json=extra_arguments) return response if __name__ == "__main__": URL_BASE = "http://127.0.0.1:8000" arguments = { "input": "We are writing snake in python. MVC components split \ in separate files. Keyboard control.", # our prompt "additional_input": {"improve_option": False}, } # create a task response = post_data(f"{URL_BASE}/agent/tasks", arguments) print(response.json()) task_id = response.json()["task_id"] sleep(1) # this is not needed # execute the step for our task response = post_data(f"{URL_BASE}/agent/tasks/{task_id}/steps", {}) print(response.json()) ================================================ FILE: sweep.yaml ================================================ # Sweep AI turns bug fixes & feature requests into code changes (https://sweep.dev) # For details on our config file, check out our docs at https://docs.sweep.dev # If you use this be sure to frequently sync your default branch(main, master) to dev. branch: 'main' # By default Sweep will read the logs and outputs from your existing Github Actions. To disable this, set this to false. gha_enabled: True description: 'Python project for AI code generation with next token prediction LLMs. Various AI steps are carried out in steps.py. Disk access via DB objects.' # Default Values: https://github.com/sweepai/sweep/blob/main/sweep.yaml sandbox: install: - pre-commit install check: - pre-commit run --files {file_path} rules: - Ensure all new functions and classes have very clear, concise and up-to-date docstrings. Take gpt_engineer/ai.py as a good example. ================================================ FILE: tests/__init__.py ================================================ ================================================ FILE: tests/ai_cache.json ================================================ {"[{\"type\": \"system\", \"data\": {\"content\": \"You will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the correct decisions to make sure we get it right.\\nFirst lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nRepresent files like so:\\n\\nFILENAME\\n```\\nCODE\\n```\\n\\nThe following tokens must be replaced like so:\\nFILENAME is the lowercase combined path and file name including the file extension\\nCODE is the code in the file\\n\\nExample representation of a file:\\n\\nsrc/hello_world.py\\n```\\nprint(\\\"Hello World\\\")\\n```\\n\\nDo not comment on what every file does. Please note that the code should be fully functional. No placeholders.\\n\\n\\nYou will start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\\nUseful to know:\\nAlmost always put different classes in different files.\\nAlways use the programming language the user asks for.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nAlways add a comment briefly describing the purpose of the function definition.\\nAdd comments explaining very complex bits of logic.\\nAlways follow the best practices for the requested languages for folder/file structure and how to package the project.\\n\\n\\nPython toolbelt preferences:\\n- pytest\\n- dataclasses\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": [{\"type\": \"text\", \"text\": \"Request: Make a program that prints 'Hello World!' to a file called 'output.txt'\"}], \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the correct decisions to make sure we get it right.\\nFirst lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nRepresent files like so:\\n\\nFILENAME\\n```\\nCODE\\n```\\n\\nThe following tokens must be replaced like so:\\nFILENAME is the lowercase combined path and file name including the file extension\\nCODE is the code in the file\\n\\nExample representation of a file:\\n\\nsrc/hello_world.py\\n```\\nprint(\\\"Hello World\\\")\\n```\\n\\nDo not comment on what every file does. Please note that the code should be fully functional. No placeholders.\\n\\n\\nYou will start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\\nUseful to know:\\nAlmost always put different classes in different files.\\nAlways use the programming language the user asks for.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nAlways add a comment briefly describing the purpose of the function definition.\\nAdd comments explaining very complex bits of logic.\\nAlways follow the best practices for the requested languages for folder/file structure and how to package the project.\\n\\n\\nPython toolbelt preferences:\\n- pytest\\n- dataclasses\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": [{\"type\": \"text\", \"text\": \"Request: Make a program that prints 'Hello World!' to a file called 'output.txt'\"}], \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"To create a Python program that writes 'Hello World!' to a file called 'output.txt', we will need the following files:\\n\\n1. `main.py`: This will be the entry point of our program. It will contain the main logic to write 'Hello World!' to the file.\\n2. `requirements.txt`: This file will list all the Python package dependencies required to run the program. In this case, there are no external dependencies, so this file will be empty.\\n\\nLet's start with the `main.py` file:\\n\\nmain.py\\n```python\\ndef write_hello_world_to_file(filename):\\n \\\"\\\"\\\"\\n Writes 'Hello World!' to the specified file.\\n \\n :param filename: The name of the file to write to.\\n \\\"\\\"\\\"\\n with open(filename, 'w') as file:\\n file.write('Hello World!')\\n\\nif __name__ == \\\"__main__\\\":\\n output_filename = 'output.txt'\\n write_hello_world_to_file(output_filename)\\n```\\n\\nNow, let's create the `requirements.txt` file, which will be empty as mentioned:\\n\\nrequirements.txt\\n```\\n# No external dependencies required\\n```\\n\\nThis concludes a fully working implementation.\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nFrom this you will answer with code blocks that includes all the necessary unix terminal commands to:\\na) install dependencies\\nb) run all necessary parts of the codebase (in parallel if necessary)\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Information about the codebase:\\n\\n```\\nFile: main.py\\n1 def write_hello_world_to_file(filename):\\n2 \\\"\\\"\\\"\\n3 Writes 'Hello World!' to the specified file.\\n4 \\n5 :param filename: The name of the file to write to.\\n6 \\\"\\\"\\\"\\n7 with open(filename, 'w') as file:\\n8 file.write('Hello World!')\\n9 \\n10 if __name__ == \\\"__main__\\\":\\n11 output_filename = 'output.txt'\\n12 write_hello_world_to_file(output_filename)\\n\\nFile: requirements.txt\\n1 # No external dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nFrom this you will answer with code blocks that includes all the necessary unix terminal commands to:\\na) install dependencies\\nb) run all necessary parts of the codebase (in parallel if necessary)\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Information about the codebase:\\n\\n```\\nFile: main.py\\n1 def write_hello_world_to_file(filename):\\n2 \\\"\\\"\\\"\\n3 Writes 'Hello World!' to the specified file.\\n4 \\n5 :param filename: The name of the file to write to.\\n6 \\\"\\\"\\\"\\n7 with open(filename, 'w') as file:\\n8 file.write('Hello World!')\\n9 \\n10 if __name__ == \\\"__main__\\\":\\n11 output_filename = 'output.txt'\\n12 write_hello_world_to_file(output_filename)\\n\\nFile: requirements.txt\\n1 # No external dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\npython3 main.py &\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": [{\"type\": \"text\", \"text\": \"Request: Make a program that prints 'Hello World!' to a file called 'output.txt'\"}], \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"You will output the content of each file necessary to achieve the goal, including ALL code.\\nRepresent files like so:\\n\\nFILENAME\\n```\\nCODE\\n```\\n\\nThe following tokens must be replaced like so:\\nFILENAME is the lowercase combined path and file name including the file extension\\nCODE is the code in the file\\n\\nExample representation of a file:\\n\\nsrc/hello_world.py\\n```\\nprint(\\\"Hello World\\\")\\n```\\n\\nDo not comment on what every file does. Please note that the code should be fully functional. No placeholders.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": [{\"type\": \"text\", \"text\": \"Request: Make a program that prints 'Hello World!' to a file called 'output.txt'\"}], \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"You will output the content of each file necessary to achieve the goal, including ALL code.\\nRepresent files like so:\\n\\nFILENAME\\n```\\nCODE\\n```\\n\\nThe following tokens must be replaced like so:\\nFILENAME is the lowercase combined path and file name including the file extension\\nCODE is the code in the file\\n\\nExample representation of a file:\\n\\nsrc/hello_world.py\\n```\\nprint(\\\"Hello World\\\")\\n```\\n\\nDo not comment on what every file does. Please note that the code should be fully functional. No placeholders.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"hello_world.py\\n```\\nwith open('output.txt', 'w') as file:\\n file.write('Hello World!\\\\n')\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nFrom this you will answer with code blocks that includes all the necessary unix terminal commands to:\\na) install dependencies\\nb) run all necessary parts of the codebase (in parallel if necessary)\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Information about the codebase:\\n\\n```\\nFile: hello_world.py\\n1 with open('output.txt', 'w') as file:\\n2 file.write('Hello World!\\\\n')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nFrom this you will answer with code blocks that includes all the necessary unix terminal commands to:\\na) install dependencies\\nb) run all necessary parts of the codebase (in parallel if necessary)\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Information about the codebase:\\n\\n```\\nFile: hello_world.py\\n1 with open('output.txt', 'w') as file:\\n2 file.write('Hello World!\\\\n')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\npython3 hello_world.py\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"Given some instructions, determine if anything needs to be clarified, do not carry them out.\\nYou can make reasonable assumptions, but if you are unsure, ask a single clarification question.\\nOtherwise state: \\\"Nothing to clarify\\\"\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Make a program that prints 'Hello World!' to a file called 'output.txt either using python or javascript'\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"Given some instructions, determine if anything needs to be clarified, do not carry them out.\\nYou can make reasonable assumptions, but if you are unsure, ask a single clarification question.\\nOtherwise state: \\\"Nothing to clarify\\\"\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Make a program that prints 'Hello World!' to a file called 'output.txt either using python or javascript'\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"Clarification question: Should the program be capable of being written in either Python or JavaScript based on user choice, or do you want two separate versions of the program, one in Python and one in JavaScript?\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"Given some instructions, determine if anything needs to be clarified, do not carry them out.\\nYou can make reasonable assumptions, but if you are unsure, ask a single clarification question.\\nOtherwise state: \\\"Nothing to clarify\\\"\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Make a program that prints 'Hello World!' to a file called 'output.txt either using python or javascript'\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"Clarification question: Should the program be capable of being written in either Python or JavaScript based on user choice, or do you want two separate versions of the program, one in Python and one in JavaScript?\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": \"y\\n \\n\\n\\n Is anything else unclear? If yes, ask another question.\\n\\n Otherwise state: \\\"Nothing to clarify\\\"\\n \", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"Given some instructions, determine if anything needs to be clarified, do not carry them out.\\nYou can make reasonable assumptions, but if you are unsure, ask a single clarification question.\\nOtherwise state: \\\"Nothing to clarify\\\"\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Make a program that prints 'Hello World!' to a file called 'output.txt either using python or javascript'\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"Clarification question: Should the program be capable of being written in either Python or JavaScript based on user choice, or do you want two separate versions of the program, one in Python and one in JavaScript?\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": \"y\\n \\n\\n\\n Is anything else unclear? If yes, ask another question.\\n\\n Otherwise state: \\\"Nothing to clarify\\\"\\n \", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"Nothing to clarify\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the correct decisions to make sure we get it right.\\nFirst lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nRepresent files like so:\\n\\nFILENAME\\n```\\nCODE\\n```\\n\\nThe following tokens must be replaced like so:\\nFILENAME is the lowercase combined path and file name including the file extension\\nCODE is the code in the file\\n\\nExample representation of a file:\\n\\nsrc/hello_world.py\\n```\\nprint(\\\"Hello World\\\")\\n```\\n\\nDo not comment on what every file does. Please note that the code should be fully functional. No placeholders.\\n\\n\\nYou will start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\\nUseful to know:\\nAlmost always put different classes in different files.\\nAlways use the programming language the user asks for.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nAlways add a comment briefly describing the purpose of the function definition.\\nAdd comments explaining very complex bits of logic.\\nAlways follow the best practices for the requested languages for folder/file structure and how to package the project.\\n\\n\\nPython toolbelt preferences:\\n- pytest\\n- dataclasses\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Make a program that prints 'Hello World!' to a file called 'output.txt either using python or javascript'\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"Clarification question: Should the program be capable of being written in either Python or JavaScript based on user choice, or do you want two separate versions of the program, one in Python and one in JavaScript?\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": \"y\\n \\n\\n\\n Is anything else unclear? If yes, ask another question.\\n\\n Otherwise state: \\\"Nothing to clarify\\\"\\n \", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"Nothing to clarify\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": \"Think step by step and reason yourself to the correct decisions to make sure we get it right.\\nFirst lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nRepresent files like so:\\n\\nFILENAME\\n```\\nCODE\\n```\\n\\nThe following tokens must be replaced like so:\\nFILENAME is the lowercase combined path and file name including the file extension\\nCODE is the code in the file\\n\\nExample representation of a file:\\n\\nsrc/hello_world.py\\n```\\nprint(\\\"Hello World\\\")\\n```\\n\\nDo not comment on what every file does. Please note that the code should be fully functional. No placeholders.\\n\\n\\nYou will start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the correct decisions to make sure we get it right.\\nFirst lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nRepresent files like so:\\n\\nFILENAME\\n```\\nCODE\\n```\\n\\nThe following tokens must be replaced like so:\\nFILENAME is the lowercase combined path and file name including the file extension\\nCODE is the code in the file\\n\\nExample representation of a file:\\n\\nsrc/hello_world.py\\n```\\nprint(\\\"Hello World\\\")\\n```\\n\\nDo not comment on what every file does. Please note that the code should be fully functional. No placeholders.\\n\\n\\nYou will start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\\nUseful to know:\\nAlmost always put different classes in different files.\\nAlways use the programming language the user asks for.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nAlways add a comment briefly describing the purpose of the function definition.\\nAdd comments explaining very complex bits of logic.\\nAlways follow the best practices for the requested languages for folder/file structure and how to package the project.\\n\\n\\nPython toolbelt preferences:\\n- pytest\\n- dataclasses\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Make a program that prints 'Hello World!' to a file called 'output.txt either using python or javascript'\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"Clarification question: Should the program be capable of being written in either Python or JavaScript based on user choice, or do you want two separate versions of the program, one in Python and one in JavaScript?\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": \"y\\n \\n\\n\\n Is anything else unclear? If yes, ask another question.\\n\\n Otherwise state: \\\"Nothing to clarify\\\"\\n \", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"Nothing to clarify\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": \"Think step by step and reason yourself to the correct decisions to make sure we get it right.\\nFirst lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nRepresent files like so:\\n\\nFILENAME\\n```\\nCODE\\n```\\n\\nThe following tokens must be replaced like so:\\nFILENAME is the lowercase combined path and file name including the file extension\\nCODE is the code in the file\\n\\nExample representation of a file:\\n\\nsrc/hello_world.py\\n```\\nprint(\\\"Hello World\\\")\\n```\\n\\nDo not comment on what every file does. Please note that the code should be fully functional. No placeholders.\\n\\n\\nYou will start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"Since the user has not specified a preference for Python or JavaScript, I will choose Python for this implementation. The program will be simple, consisting of a single script that writes \\\"Hello World!\\\" to a file named `output.txt`.\\n\\nThe core function necessary for this task is a function that encapsulates the file writing operation. This function will be named `write_hello_world` and its purpose is to open a file in write mode and output the string \\\"Hello World!\\\" to it.\\n\\nLet's start with the entrypoint file:\\n\\nmain.py\\n```python\\ndef write_hello_world(file_path):\\n with open(file_path, 'w') as file:\\n file.write(\\\"Hello World!\\\\n\\\")\\n\\nif __name__ == \\\"__main__\\\":\\n write_hello_world('output.txt')\\n```\\n\\nSince this is a very simple Python script, there are no additional imports or classes needed, and no external dependencies to include in a `requirements.txt` file. The script can be run directly in a Python environment.\\n\\nThis concludes a fully working implementation.\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nFrom this you will answer with code blocks that includes all the necessary unix terminal commands to:\\na) install dependencies\\nb) run all necessary parts of the codebase (in parallel if necessary)\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Information about the codebase:\\n\\n```\\nFile: main.py\\n1 def write_hello_world(file_path):\\n2 with open(file_path, 'w') as file:\\n3 file.write(\\\"Hello World!\\\\n\\\")\\n4 \\n5 if __name__ == \\\"__main__\\\":\\n6 write_hello_world('output.txt')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nFrom this you will answer with code blocks that includes all the necessary unix terminal commands to:\\na) install dependencies\\nb) run all necessary parts of the codebase (in parallel if necessary)\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Information about the codebase:\\n\\n```\\nFile: main.py\\n1 def write_hello_world(file_path):\\n2 with open(file_path, 'w') as file:\\n3 file.write(\\\"Hello World!\\\\n\\\")\\n4 \\n5 if __name__ == \\\"__main__\\\":\\n6 write_hello_world('output.txt')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\npython3 main.py\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the correct decisions to make sure we get it right.\\nMake changes to existing code and implement new code in the unified git diff syntax. When implementing new code, First lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nOutput requested code changes and new code in the unified \\\"git diff\\\" syntax. Example:\\n\\n```diff\\n--- example.txt\\n+++ example.txt\\n@@ -6,3 +6,4 @@\\n line content A\\n line content B\\n+ new line added\\n- original line X\\n+ modified line X with changes\\n@@ -26,4 +27,5 @@\\n condition check:\\n- action for condition A\\n+ if certain condition is met:\\n+ alternative action for condition A\\n another condition check:\\n- action for condition B\\n+ modified action for condition B\\n```\\n\\nExample of a git diff creating a new file:\\n\\n```diff\\n--- /dev/null\\n+++ new_file.txt\\n@@ -0,0 +1,3 @@\\n+First example line\\n+\\n+Last example line\\n```\\n-A program will apply the diffs you generate exactly to the code, so diffs must be precise and unambiguous!\\n-Every diff must be fenced with triple backtick ```.\\n-The file names at the beginning of a diff, (lines starting with --- and +++) is the relative path to the file before and after the diff.\\n-LINES TO BE REMOVED (starting with single -) AND LINES TO BE RETAIN (no starting symbol) HAVE TO REPLICATE THE DIFFED HUNK OF THE CODE EXACTLY LINE BY LINE. KEEP THE NUMBER OF RETAIN LINES SMALL IF POSSIBLE.\\n-EACH LINE IN THE SOURCE FILES STARTS WITH A LINE NUMBER, WHICH IS NOT PART OF THE SOURCE CODE. NEVER TRANSFER THESE LINE NUMBERS TO THE DIFF HUNKS.\\n-AVOID STARTING A HUNK WITH AN EMPTY LINE.\\n\\n\\nAs far as compatible with the user request, start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\\nUseful to know:\\nAlmost always put different classes in different files.\\nAlways use the programming language the user asks for.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nAlways add a comment briefly describing the purpose of the function definition.\\nAdd comments explaining very complex bits of logic.\\nAlways follow the best practices for the requested languages for folder/file structure and how to package the project.\\n\\n\\nPython toolbelt preferences:\\n- pytest\\n- dataclasses\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"```\\nFile: main.py\\n1 def write_hello_world_to_file(filename):\\n2 \\\"\\\"\\\"\\n3 Writes 'Hello World!' to the specified file.\\n4 \\n5 :param filename: The name of the file to write to.\\n6 \\\"\\\"\\\"\\n7 with open(filename, 'w') as file:\\n8 file.write('Hello World!')\\n9 \\n10 if __name__ == \\\"__main__\\\":\\n11 output_filename = 'output.txt'\\n12 write_hello_world_to_file(output_filename)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\nFile: run.sh\\n1 python3 main.py\\n2 \\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": [{\"type\": \"text\", \"text\": \"Request: Change the program so that it prints '!dlroW olleH' instead of 'Hello World!'\"}], \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": \"Request: Prompt(text=\\\"Change the program so that it prints '!dlroW olleH' instead of 'Hello World!'\\\", image_urls=None)\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the correct decisions to make sure we get it right.\\nMake changes to existing code and implement new code in the unified git diff syntax. When implementing new code, First lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nOutput requested code changes and new code in the unified \\\"git diff\\\" syntax. Example:\\n\\n```diff\\n--- example.txt\\n+++ example.txt\\n@@ -6,3 +6,4 @@\\n line content A\\n line content B\\n+ new line added\\n- original line X\\n+ modified line X with changes\\n@@ -26,4 +27,5 @@\\n condition check:\\n- action for condition A\\n+ if certain condition is met:\\n+ alternative action for condition A\\n another condition check:\\n- action for condition B\\n+ modified action for condition B\\n```\\n\\nExample of a git diff creating a new file:\\n\\n```diff\\n--- /dev/null\\n+++ new_file.txt\\n@@ -0,0 +1,3 @@\\n+First example line\\n+\\n+Last example line\\n```\\n-A program will apply the diffs you generate exactly to the code, so diffs must be precise and unambiguous!\\n-Every diff must be fenced with triple backtick ```.\\n-The file names at the beginning of a diff, (lines starting with --- and +++) is the relative path to the file before and after the diff.\\n-LINES TO BE REMOVED (starting with single -) AND LINES TO BE RETAIN (no starting symbol) HAVE TO REPLICATE THE DIFFED HUNK OF THE CODE EXACTLY LINE BY LINE. KEEP THE NUMBER OF RETAIN LINES SMALL IF POSSIBLE.\\n-EACH LINE IN THE SOURCE FILES STARTS WITH A LINE NUMBER, WHICH IS NOT PART OF THE SOURCE CODE. NEVER TRANSFER THESE LINE NUMBERS TO THE DIFF HUNKS.\\n-AVOID STARTING A HUNK WITH AN EMPTY LINE.\\n\\n\\nAs far as compatible with the user request, start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\\nUseful to know:\\nAlmost always put different classes in different files.\\nAlways use the programming language the user asks for.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nAlways add a comment briefly describing the purpose of the function definition.\\nAdd comments explaining very complex bits of logic.\\nAlways follow the best practices for the requested languages for folder/file structure and how to package the project.\\n\\n\\nPython toolbelt preferences:\\n- pytest\\n- dataclasses\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"```\\nFile: main.py\\n1 def write_hello_world_to_file(filename):\\n2 \\\"\\\"\\\"\\n3 Writes 'Hello World!' to the specified file.\\n4 \\n5 :param filename: The name of the file to write to.\\n6 \\\"\\\"\\\"\\n7 with open(filename, 'w') as file:\\n8 file.write('Hello World!')\\n9 \\n10 if __name__ == \\\"__main__\\\":\\n11 output_filename = 'output.txt'\\n12 write_hello_world_to_file(output_filename)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\nFile: run.sh\\n1 python3 main.py\\n2 \\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": [{\"type\": \"text\", \"text\": \"Request: Change the program so that it prints '!dlroW olleH' instead of 'Hello World!'\"}], \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": \"Request: Prompt(text=\\\"Change the program so that it prints '!dlroW olleH' instead of 'Hello World!'\\\", image_urls=None)\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```diff\\n--- main.py\\n+++ main.py\\n@@ -7,3 +7,3 @@\\n with open(filename, 'w') as file:\\n- file.write('Hello World!')\\n+ file.write('!dlroW olleH')\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the correct decisions to make sure we get it right.\\nFirst lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nRepresent files like so:\\n\\nFILENAME\\n```\\nCODE\\n```\\n\\nThe following tokens must be replaced like so:\\nFILENAME is the lowercase combined path and file name including the file extension\\nCODE is the code in the file\\n\\nExample representation of a file:\\n\\nsrc/hello_world.py\\n```\\nprint(\\\"Hello World\\\")\\n```\\n\\nDo not comment on what every file does. Please note that the code should be fully functional. No placeholders.\\n\\n\\nYou will start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\\nUseful to know:\\nAlmost always put different classes in different files.\\nAlways use the programming language the user asks for.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nAlways add a comment briefly describing the purpose of the function definition.\\nAdd comments explaining very complex bits of logic.\\nAlways follow the best practices for the requested languages for folder/file structure and how to package the project.\\n\\n\\nPython toolbelt preferences:\\n- pytest\\n- dataclasses\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": [{\"type\": \"text\", \"text\": \"Request: Make a python program that writes 'hello' to a file called 'output.txt'\"}], \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the correct decisions to make sure we get it right.\\nFirst lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nRepresent files like so:\\n\\nFILENAME\\n```\\nCODE\\n```\\n\\nThe following tokens must be replaced like so:\\nFILENAME is the lowercase combined path and file name including the file extension\\nCODE is the code in the file\\n\\nExample representation of a file:\\n\\nsrc/hello_world.py\\n```\\nprint(\\\"Hello World\\\")\\n```\\n\\nDo not comment on what every file does. Please note that the code should be fully functional. No placeholders.\\n\\n\\nYou will start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\\nUseful to know:\\nAlmost always put different classes in different files.\\nAlways use the programming language the user asks for.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nAlways add a comment briefly describing the purpose of the function definition.\\nAdd comments explaining very complex bits of logic.\\nAlways follow the best practices for the requested languages for folder/file structure and how to package the project.\\n\\n\\nPython toolbelt preferences:\\n- pytest\\n- dataclasses\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": [{\"type\": \"text\", \"text\": \"Request: Make a python program that writes 'hello' to a file called 'output.txt'\"}], \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"To create a Python program that writes 'hello' to a file called 'output.txt', we will need the following components:\\n\\n1. `main.py`: The entry point of the program that contains the main logic to write 'hello' to the file.\\n2. `file_writer.py`: A utility module that provides a function to write text to a file.\\n3. `requirements.txt`: A file to list the dependencies for the project, although for this simple task, no external dependencies are required.\\n\\nLet's start by creating the `main.py` file:\\n\\nmain.py\\n```python\\nfrom file_writer import write_to_file\\n\\ndef main():\\n # The text to be written to the file\\n text_to_write = \\\"hello\\\"\\n # The filename of the file to write to\\n output_filename = \\\"output.txt\\\"\\n # Write the text to the file\\n write_to_file(output_filename, text_to_write)\\n\\nif __name__ == \\\"__main__\\\":\\n main()\\n```\\n\\nNow, let's create the `file_writer.py` file that contains the `write_to_file` function:\\n\\nfile_writer.py\\n```python\\ndef write_to_file(filename, text):\\n \\\"\\\"\\\"\\n Writes the given text to a file with the specified filename.\\n \\\"\\\"\\\"\\n with open(filename, 'w') as file:\\n file.write(text)\\n```\\n\\nSince this program does not require any external dependencies, the `requirements.txt` file will be empty but included for completeness:\\n\\nrequirements.txt\\n```\\n# No dependencies required\\n```\\n\\nThis concludes a fully working implementation.\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nFrom this you will answer with code blocks that includes all the necessary unix terminal commands to:\\na) install dependencies\\nb) run all necessary parts of the codebase (in parallel if necessary)\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Information about the codebase:\\n\\n```\\nFile: main.py\\n1 from file_writer import write_to_file\\n2 \\n3 def main():\\n4 # The text to be written to the file\\n5 text_to_write = \\\"hello\\\"\\n6 # The filename of the file to write to\\n7 output_filename = \\\"output.txt\\\"\\n8 # Write the text to the file\\n9 write_to_file(output_filename, text_to_write)\\n10 \\n11 if __name__ == \\\"__main__\\\":\\n12 main()\\n\\nFile: file_writer.py\\n1 def write_to_file(filename, text):\\n2 \\\"\\\"\\\"\\n3 Writes the given text to a file with the specified filename.\\n4 \\\"\\\"\\\"\\n5 with open(filename, 'w') as file:\\n6 file.write(text)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nFrom this you will answer with code blocks that includes all the necessary unix terminal commands to:\\na) install dependencies\\nb) run all necessary parts of the codebase (in parallel if necessary)\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Information about the codebase:\\n\\n```\\nFile: main.py\\n1 from file_writer import write_to_file\\n2 \\n3 def main():\\n4 # The text to be written to the file\\n5 text_to_write = \\\"hello\\\"\\n6 # The filename of the file to write to\\n7 output_filename = \\\"output.txt\\\"\\n8 # Write the text to the file\\n9 write_to_file(output_filename, text_to_write)\\n10 \\n11 if __name__ == \\\"__main__\\\":\\n12 main()\\n\\nFile: file_writer.py\\n1 def write_to_file(filename, text):\\n2 \\\"\\\"\\\"\\n3 Writes the given text to a file with the specified filename.\\n4 \\\"\\\"\\\"\\n5 with open(filename, 'w') as file:\\n6 file.write(text)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\npython3 main.py\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the correct decisions to make sure we get it right.\\nMake changes to existing code and implement new code in the unified git diff syntax. When implementing new code, First lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nOutput requested code changes and new code in the unified \\\"git diff\\\" syntax. Example:\\n\\n```diff\\n--- example.txt\\n+++ example.txt\\n@@ -6,3 +6,4 @@\\n line content A\\n line content B\\n+ new line added\\n- original line X\\n+ modified line X with changes\\n@@ -26,4 +27,5 @@\\n condition check:\\n- action for condition A\\n+ if certain condition is met:\\n+ alternative action for condition A\\n another condition check:\\n- action for condition B\\n+ modified action for condition B\\n```\\n\\nExample of a git diff creating a new file:\\n\\n```diff\\n--- /dev/null\\n+++ new_file.txt\\n@@ -0,0 +1,3 @@\\n+First example line\\n+\\n+Last example line\\n```\\n-A program will apply the diffs you generate exactly to the code, so diffs must be precise and unambiguous!\\n-Every diff must be fenced with triple backtick ```.\\n-The file names at the beginning of a diff, (lines starting with --- and +++) is the relative path to the file before and after the diff.\\n-LINES TO BE REMOVED (starting with single -) AND LINES TO BE RETAIN (no starting symbol) HAVE TO REPLICATE THE DIFFED HUNK OF THE CODE EXACTLY LINE BY LINE. KEEP THE NUMBER OF RETAIN LINES SMALL IF POSSIBLE.\\n-EACH LINE IN THE SOURCE FILES STARTS WITH A LINE NUMBER, WHICH IS NOT PART OF THE SOURCE CODE. NEVER TRANSFER THESE LINE NUMBERS TO THE DIFF HUNKS.\\n-AVOID STARTING A HUNK WITH AN EMPTY LINE.\\n\\n\\nAs far as compatible with the user request, start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\\nUseful to know:\\nAlmost always put different classes in different files.\\nAlways use the programming language the user asks for.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nAlways add a comment briefly describing the purpose of the function definition.\\nAdd comments explaining very complex bits of logic.\\nAlways follow the best practices for the requested languages for folder/file structure and how to package the project.\\n\\n\\nPython toolbelt preferences:\\n- pytest\\n- dataclasses\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"```\\nFile: main.py\\n1 The program will be written in this file\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": [{\"type\": \"text\", \"text\": \"Request: Make a python program that writes 'hello' to a file called 'output.txt'\"}], \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": \"Request: Prompt(text=\\\"Make a python program that writes 'hello' to a file called 'output.txt'\\\", image_urls=None)\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the correct decisions to make sure we get it right.\\nMake changes to existing code and implement new code in the unified git diff syntax. When implementing new code, First lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nOutput requested code changes and new code in the unified \\\"git diff\\\" syntax. Example:\\n\\n```diff\\n--- example.txt\\n+++ example.txt\\n@@ -6,3 +6,4 @@\\n line content A\\n line content B\\n+ new line added\\n- original line X\\n+ modified line X with changes\\n@@ -26,4 +27,5 @@\\n condition check:\\n- action for condition A\\n+ if certain condition is met:\\n+ alternative action for condition A\\n another condition check:\\n- action for condition B\\n+ modified action for condition B\\n```\\n\\nExample of a git diff creating a new file:\\n\\n```diff\\n--- /dev/null\\n+++ new_file.txt\\n@@ -0,0 +1,3 @@\\n+First example line\\n+\\n+Last example line\\n```\\n-A program will apply the diffs you generate exactly to the code, so diffs must be precise and unambiguous!\\n-Every diff must be fenced with triple backtick ```.\\n-The file names at the beginning of a diff, (lines starting with --- and +++) is the relative path to the file before and after the diff.\\n-LINES TO BE REMOVED (starting with single -) AND LINES TO BE RETAIN (no starting symbol) HAVE TO REPLICATE THE DIFFED HUNK OF THE CODE EXACTLY LINE BY LINE. KEEP THE NUMBER OF RETAIN LINES SMALL IF POSSIBLE.\\n-EACH LINE IN THE SOURCE FILES STARTS WITH A LINE NUMBER, WHICH IS NOT PART OF THE SOURCE CODE. NEVER TRANSFER THESE LINE NUMBERS TO THE DIFF HUNKS.\\n-AVOID STARTING A HUNK WITH AN EMPTY LINE.\\n\\n\\nAs far as compatible with the user request, start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\\nUseful to know:\\nAlmost always put different classes in different files.\\nAlways use the programming language the user asks for.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nAlways add a comment briefly describing the purpose of the function definition.\\nAdd comments explaining very complex bits of logic.\\nAlways follow the best practices for the requested languages for folder/file structure and how to package the project.\\n\\n\\nPython toolbelt preferences:\\n- pytest\\n- dataclasses\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"```\\nFile: main.py\\n1 The program will be written in this file\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": [{\"type\": \"text\", \"text\": \"Request: Make a python program that writes 'hello' to a file called 'output.txt'\"}], \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": \"Request: Prompt(text=\\\"Make a python program that writes 'hello' to a file called 'output.txt'\\\", image_urls=None)\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"To create a Python program that writes 'hello' to a file called 'output.txt', we will need to perform the following steps:\\n\\n1. Open the file 'output.txt' in write mode.\\n2. Write the string 'hello' to the file.\\n3. Close the file to ensure the data is written and the file is not left open.\\n\\nLet's start by creating the main Python script (`main.py`) that will contain the logic to write to the file.\\n\\n```diff\\n--- /dev/null\\n+++ main.py\\n@@ -0,0 +1,10 @@\\n+def write_hello_to_file(filename):\\n+ \\\"\\\"\\\"Write the string 'hello' to the specified file.\\\"\\\"\\\"\\n+ with open(filename, 'w') as file:\\n+ file.write('hello')\\n+\\n+if __name__ == '__main__':\\n+ output_filename = 'output.txt'\\n+ write_hello_to_file(output_filename)\\n+ print(f\\\"'hello' has been written to {output_filename}\\\")\\n```\\n\\nThis code defines a function `write_hello_to_file` that takes a filename as an argument and writes 'hello' to that file. The `if __name__ == '__main__':` block ensures that the code runs only if the script is executed as the main program and not when imported as a module.\\n\\nNext, we will create a `requirements.txt` file to list any dependencies. Since this script uses only the standard library, the `requirements.txt` will be empty, but it's a good practice to include it for future extensibility.\\n\\n```diff\\n--- /dev/null\\n+++ requirements.txt\\n@@ -0,0 +1 @@\\n+# No dependencies required for this script\\n```\\n\\nThis concludes a fully working implementation.\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": [{\"type\": \"text\", \"text\": \"Request: Make a python program that writes 'hello' to a file called 'output.txt'\"}], \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"You will output the content of each file necessary to achieve the goal, including ALL code.\\nRepresent files like so:\\n\\nFILENAME\\n```\\nCODE\\n```\\n\\nThe following tokens must be replaced like so:\\nFILENAME is the lowercase combined path and file name including the file extension\\nCODE is the code in the file\\n\\nExample representation of a file:\\n\\nsrc/hello_world.py\\n```\\nprint(\\\"Hello World\\\")\\n```\\n\\nDo not comment on what every file does. Please note that the code should be fully functional. No placeholders.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": [{\"type\": \"text\", \"text\": \"Request: Make a python program that writes 'hello' to a file called 'output.txt'\"}], \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"You will output the content of each file necessary to achieve the goal, including ALL code.\\nRepresent files like so:\\n\\nFILENAME\\n```\\nCODE\\n```\\n\\nThe following tokens must be replaced like so:\\nFILENAME is the lowercase combined path and file name including the file extension\\nCODE is the code in the file\\n\\nExample representation of a file:\\n\\nsrc/hello_world.py\\n```\\nprint(\\\"Hello World\\\")\\n```\\n\\nDo not comment on what every file does. Please note that the code should be fully functional. No placeholders.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"write_hello.py\\n```\\n# This Python script writes 'hello' to a file called 'output.txt'\\n\\nwith open('output.txt', 'w') as file:\\n file.write('hello')\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nFrom this you will answer with code blocks that includes all the necessary unix terminal commands to:\\na) install dependencies\\nb) run all necessary parts of the codebase (in parallel if necessary)\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Information about the codebase:\\n\\n```\\nFile: write_hello.py\\n1 # This Python script writes 'hello' to a file called 'output.txt'\\n2 \\n3 with open('output.txt', 'w') as file:\\n4 file.write('hello')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nFrom this you will answer with code blocks that includes all the necessary unix terminal commands to:\\na) install dependencies\\nb) run all necessary parts of the codebase (in parallel if necessary)\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Information about the codebase:\\n\\n```\\nFile: write_hello.py\\n1 # This Python script writes 'hello' to a file called 'output.txt'\\n2 \\n3 with open('output.txt', 'w') as file:\\n4 file.write('hello')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\npython3 -m venv venv\\nsource venv/bin/activate\\npip install -r requirements.txt\\npython write_hello.py &\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"Given some instructions, determine if anything needs to be clarified, do not carry them out.\\nYou can make reasonable assumptions, but if you are unsure, ask a single clarification question.\\nOtherwise state: \\\"Nothing to clarify\\\"\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Make a python program that writes 'hello' to a file called 'output.txt'\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"Given some instructions, determine if anything needs to be clarified, do not carry them out.\\nYou can make reasonable assumptions, but if you are unsure, ask a single clarification question.\\nOtherwise state: \\\"Nothing to clarify\\\"\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Make a python program that writes 'hello' to a file called 'output.txt'\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"Nothing to clarify\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the correct decisions to make sure we get it right.\\nFirst lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nRepresent files like so:\\n\\nFILENAME\\n```\\nCODE\\n```\\n\\nThe following tokens must be replaced like so:\\nFILENAME is the lowercase combined path and file name including the file extension\\nCODE is the code in the file\\n\\nExample representation of a file:\\n\\nsrc/hello_world.py\\n```\\nprint(\\\"Hello World\\\")\\n```\\n\\nDo not comment on what every file does. Please note that the code should be fully functional. No placeholders.\\n\\n\\nYou will start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\\nUseful to know:\\nAlmost always put different classes in different files.\\nAlways use the programming language the user asks for.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nAlways add a comment briefly describing the purpose of the function definition.\\nAdd comments explaining very complex bits of logic.\\nAlways follow the best practices for the requested languages for folder/file structure and how to package the project.\\n\\n\\nPython toolbelt preferences:\\n- pytest\\n- dataclasses\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Make a python program that writes 'hello' to a file called 'output.txt'\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"Nothing to clarify\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": \"Think step by step and reason yourself to the correct decisions to make sure we get it right.\\nFirst lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nRepresent files like so:\\n\\nFILENAME\\n```\\nCODE\\n```\\n\\nThe following tokens must be replaced like so:\\nFILENAME is the lowercase combined path and file name including the file extension\\nCODE is the code in the file\\n\\nExample representation of a file:\\n\\nsrc/hello_world.py\\n```\\nprint(\\\"Hello World\\\")\\n```\\n\\nDo not comment on what every file does. Please note that the code should be fully functional. No placeholders.\\n\\n\\nYou will start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the correct decisions to make sure we get it right.\\nFirst lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nRepresent files like so:\\n\\nFILENAME\\n```\\nCODE\\n```\\n\\nThe following tokens must be replaced like so:\\nFILENAME is the lowercase combined path and file name including the file extension\\nCODE is the code in the file\\n\\nExample representation of a file:\\n\\nsrc/hello_world.py\\n```\\nprint(\\\"Hello World\\\")\\n```\\n\\nDo not comment on what every file does. Please note that the code should be fully functional. No placeholders.\\n\\n\\nYou will start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\\nUseful to know:\\nAlmost always put different classes in different files.\\nAlways use the programming language the user asks for.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nAlways add a comment briefly describing the purpose of the function definition.\\nAdd comments explaining very complex bits of logic.\\nAlways follow the best practices for the requested languages for folder/file structure and how to package the project.\\n\\n\\nPython toolbelt preferences:\\n- pytest\\n- dataclasses\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Make a python program that writes 'hello' to a file called 'output.txt'\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"Nothing to clarify\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": \"Think step by step and reason yourself to the correct decisions to make sure we get it right.\\nFirst lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nRepresent files like so:\\n\\nFILENAME\\n```\\nCODE\\n```\\n\\nThe following tokens must be replaced like so:\\nFILENAME is the lowercase combined path and file name including the file extension\\nCODE is the code in the file\\n\\nExample representation of a file:\\n\\nsrc/hello_world.py\\n```\\nprint(\\\"Hello World\\\")\\n```\\n\\nDo not comment on what every file does. Please note that the code should be fully functional. No placeholders.\\n\\n\\nYou will start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"To achieve the goal of writing 'hello' to a file called 'output.txt', we will need a simple Python script with a main function that handles the file writing. There is no need for multiple classes or complex structures for this task. The script will be self-contained in a single file.\\n\\nHere is the content of the Python script:\\n\\nmain.py\\n```\\ndef write_hello_to_file(filename):\\n \\\"\\\"\\\"\\n Writes 'hello' to the specified file.\\n \\\"\\\"\\\"\\n with open(filename, 'w') as file:\\n file.write('hello')\\n\\nif __name__ == '__main__':\\n write_hello_to_file('output.txt')\\n```\\n\\nThis script defines a function `write_hello_to_file` that takes a filename as an argument and writes the string 'hello' to it. The `if __name__ == '__main__':` block checks if the script is being run directly (not imported as a module) and if so, it calls the `write_hello_to_file` function with 'output.txt' as the argument.\\n\\nSince this is a very basic script, there are no additional dependencies, so there is no need for a `requirements.txt` file.\\n\\nThis concludes a fully working implementation.\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nFrom this you will answer with code blocks that includes all the necessary unix terminal commands to:\\na) install dependencies\\nb) run all necessary parts of the codebase (in parallel if necessary)\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Information about the codebase:\\n\\n```\\nFile: main.py\\n1 def write_hello_to_file(filename):\\n2 \\\"\\\"\\\"\\n3 Writes 'hello' to the specified file.\\n4 \\\"\\\"\\\"\\n5 with open(filename, 'w') as file:\\n6 file.write('hello')\\n7 \\n8 if __name__ == '__main__':\\n9 write_hello_to_file('output.txt')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nFrom this you will answer with code blocks that includes all the necessary unix terminal commands to:\\na) install dependencies\\nb) run all necessary parts of the codebase (in parallel if necessary)\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Information about the codebase:\\n\\n```\\nFile: main.py\\n1 def write_hello_to_file(filename):\\n2 \\\"\\\"\\\"\\n3 Writes 'hello' to the specified file.\\n4 \\\"\\\"\\\"\\n5 with open(filename, 'w') as file:\\n6 file.write('hello')\\n7 \\n8 if __name__ == '__main__':\\n9 write_hello_to_file('output.txt')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\npython3 main.py\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the correct decisions to make sure we get it right.\\nFirst lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nRepresent files like so:\\n\\nFILENAME\\n```\\nCODE\\n```\\n\\nThe following tokens must be replaced like so:\\nFILENAME is the lowercase combined path and file name including the file extension\\nCODE is the code in the file\\n\\nExample representation of a file:\\n\\nsrc/hello_world.py\\n```\\nprint(\\\"Hello World\\\")\\n```\\n\\nDo not comment on what every file does. Please note that the code should be fully functional. No placeholders.\\n\\n\\nYou will start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\\nUseful to know:\\nAlmost always put different classes in different files.\\nAlways use the programming language the user asks for.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nAlways add a comment briefly describing the purpose of the function definition.\\nAdd comments explaining very complex bits of logic.\\nAlways follow the best practices for the requested languages for folder/file structure and how to package the project.\\n\\n\\nPython toolbelt preferences:\\n- pytest\\n- dataclasses\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": [{\"type\": \"text\", \"text\": \"Request: make a program that prints the outcome of 4+4\"}], \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the correct decisions to make sure we get it right.\\nFirst lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nRepresent files like so:\\n\\nFILENAME\\n```\\nCODE\\n```\\n\\nThe following tokens must be replaced like so:\\nFILENAME is the lowercase combined path and file name including the file extension\\nCODE is the code in the file\\n\\nExample representation of a file:\\n\\nsrc/hello_world.py\\n```\\nprint(\\\"Hello World\\\")\\n```\\n\\nDo not comment on what every file does. Please note that the code should be fully functional. No placeholders.\\n\\n\\nYou will start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\\nUseful to know:\\nAlmost always put different classes in different files.\\nAlways use the programming language the user asks for.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nAlways add a comment briefly describing the purpose of the function definition.\\nAdd comments explaining very complex bits of logic.\\nAlways follow the best practices for the requested languages for folder/file structure and how to package the project.\\n\\n\\nPython toolbelt preferences:\\n- pytest\\n- dataclasses\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": [{\"type\": \"text\", \"text\": \"Request: make a program that prints the outcome of 4+4\"}], \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"To create a simple Python program that prints the outcome of the operation 4+4, we will need a single Python file as the entry point. We will follow the best practices for Python file naming and structure. Since this is a very simple program, we do not need multiple classes or complex architecture. We will also include a `requirements.txt` file, although for such a simple script, it will be empty as no external libraries are required.\\n\\nHere is the content of the Python script:\\n\\nmain.py\\n```python\\ndef calculate_and_print_sum(a, b):\\n \\\"\\\"\\\"Calculate the sum of two numbers and print the result.\\\"\\\"\\\"\\n result = a + b\\n print(result)\\n\\nif __name__ == \\\"__main__\\\":\\n calculate_and_print_sum(4, 4)\\n```\\n\\nAnd the `requirements.txt` file:\\n\\nrequirements.txt\\n```\\n# No dependencies required\\n```\\n\\nThis concludes a fully working implementation.\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nFrom this you will answer with code blocks that includes all the necessary unix terminal commands to:\\na) install dependencies\\nb) run all necessary parts of the codebase (in parallel if necessary)\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Information about the codebase:\\n\\n```\\nFile: main.py\\n1 def calculate_and_print_sum(a, b):\\n2 \\\"\\\"\\\"Calculate the sum of two numbers and print the result.\\\"\\\"\\\"\\n3 result = a + b\\n4 print(result)\\n5 \\n6 if __name__ == \\\"__main__\\\":\\n7 calculate_and_print_sum(4, 4)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nFrom this you will answer with code blocks that includes all the necessary unix terminal commands to:\\na) install dependencies\\nb) run all necessary parts of the codebase (in parallel if necessary)\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"Information about the codebase:\\n\\n```\\nFile: main.py\\n1 def calculate_and_print_sum(a, b):\\n2 \\\"\\\"\\\"Calculate the sum of two numbers and print the result.\\\"\\\"\\\"\\n3 result = a + b\\n4 print(result)\\n5 \\n6 if __name__ == \\\"__main__\\\":\\n7 calculate_and_print_sum(4, 4)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\npython3 main.py\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n\\n Information about the codebase:\\n\\n```\\nFile: main.py\\n1 def write_hello_world_to_file(filename):\\n2 \\\"\\\"\\\"\\n3 Writes 'Hello World!' to the specified file.\\n4 \\n5 :param filename: The name of the file to write to.\\n6 \\\"\\\"\\\"\\n7 with open(filename, 'w') as file:\\n8 file.write('Hello World!')\\n9 \\n10 if __name__ == \\\"__main__\\\":\\n11 output_filename = 'output.txt'\\n12 write_hello_world_to_file(output_filename)\\n\\nFile: requirements.txt\\n1 # No external dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n\\n Information about the codebase:\\n\\n```\\nFile: main.py\\n1 def write_hello_world_to_file(filename):\\n2 \\\"\\\"\\\"\\n3 Writes 'Hello World!' to the specified file.\\n4 \\n5 :param filename: The name of the file to write to.\\n6 \\\"\\\"\\\"\\n7 with open(filename, 'w') as file:\\n8 file.write('Hello World!')\\n9 \\n10 if __name__ == \\\"__main__\\\":\\n11 output_filename = 'output.txt'\\n12 write_hello_world_to_file(output_filename)\\n\\nFile: requirements.txt\\n1 # No external dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\n#!/bin/bash\\n\\n# a) Install dependencies (none required as per requirements.txt, but this is how you would do it)\\n# pip install -r requirements.txt\\n\\n# b) Run the main.py script\\npython main.py &\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n\\n Information about the codebase:\\n\\n```\\nFile: hello_world.py\\n1 with open('output.txt', 'w') as file:\\n2 file.write('Hello World!\\\\n')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n\\n Information about the codebase:\\n\\n```\\nFile: hello_world.py\\n1 with open('output.txt', 'w') as file:\\n2 file.write('Hello World!\\\\n')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\n#!/bin/bash\\n\\n# a) Install dependencies\\n# No dependencies are needed for this Python script\\n\\n# b) Run the necessary parts of the codebase\\npython hello_world.py &\\nwait\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n\\n Information about the codebase:\\n\\n```\\nFile: main.py\\n1 def write_hello_world(file_path):\\n2 with open(file_path, 'w') as file:\\n3 file.write(\\\"Hello World!\\\\n\\\")\\n4 \\n5 if __name__ == \\\"__main__\\\":\\n6 write_hello_world('output.txt')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n\\n Information about the codebase:\\n\\n```\\nFile: main.py\\n1 def write_hello_world(file_path):\\n2 with open(file_path, 'w') as file:\\n3 file.write(\\\"Hello World!\\\\n\\\")\\n4 \\n5 if __name__ == \\\"__main__\\\":\\n6 write_hello_world('output.txt')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\n#!/bin/bash\\n\\n# a) Install dependencies\\n# No dependencies are needed for this script.\\n\\n# b) Run the codebase\\npython main.py &\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n\\n Information about the codebase:\\n\\n```\\nFile: main.py\\n1 from file_writer import write_to_file\\n2 \\n3 def main():\\n4 # The text to be written to the file\\n5 text_to_write = \\\"hello\\\"\\n6 # The filename of the file to write to\\n7 output_filename = \\\"output.txt\\\"\\n8 # Write the text to the file\\n9 write_to_file(output_filename, text_to_write)\\n10 \\n11 if __name__ == \\\"__main__\\\":\\n12 main()\\n\\nFile: file_writer.py\\n1 def write_to_file(filename, text):\\n2 \\\"\\\"\\\"\\n3 Writes the given text to a file with the specified filename.\\n4 \\\"\\\"\\\"\\n5 with open(filename, 'w') as file:\\n6 file.write(text)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n\\n Information about the codebase:\\n\\n```\\nFile: main.py\\n1 from file_writer import write_to_file\\n2 \\n3 def main():\\n4 # The text to be written to the file\\n5 text_to_write = \\\"hello\\\"\\n6 # The filename of the file to write to\\n7 output_filename = \\\"output.txt\\\"\\n8 # Write the text to the file\\n9 write_to_file(output_filename, text_to_write)\\n10 \\n11 if __name__ == \\\"__main__\\\":\\n12 main()\\n\\nFile: file_writer.py\\n1 def write_to_file(filename, text):\\n2 \\\"\\\"\\\"\\n3 Writes the given text to a file with the specified filename.\\n4 \\\"\\\"\\\"\\n5 with open(filename, 'w') as file:\\n6 file.write(text)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\n#!/bin/bash\\n\\n# a) Install dependencies (none required as per requirements.txt, but this is how you would do it)\\n# pip install -r requirements.txt\\n\\n# b) Run the main.py script\\npython main.py &\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n\\n Information about the codebase:\\n\\n```\\nFile: write_hello.py\\n1 # This Python script writes 'hello' to a file called 'output.txt'\\n2 \\n3 with open('output.txt', 'w') as file:\\n4 file.write('hello')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n\\n Information about the codebase:\\n\\n```\\nFile: write_hello.py\\n1 # This Python script writes 'hello' to a file called 'output.txt'\\n2 \\n3 with open('output.txt', 'w') as file:\\n4 file.write('hello')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\n#!/bin/bash\\n\\n# a) Install dependencies\\n# No dependencies are needed for this script\\n\\n# b) Run the necessary parts of the codebase\\npython write_hello.py &\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n\\n Information about the codebase:\\n\\n```\\nFile: main.py\\n1 def write_hello_to_file(filename):\\n2 \\\"\\\"\\\"\\n3 Writes 'hello' to the specified file.\\n4 \\\"\\\"\\\"\\n5 with open(filename, 'w') as file:\\n6 file.write('hello')\\n7 \\n8 if __name__ == '__main__':\\n9 write_hello_to_file('output.txt')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n\\n Information about the codebase:\\n\\n```\\nFile: main.py\\n1 def write_hello_to_file(filename):\\n2 \\\"\\\"\\\"\\n3 Writes 'hello' to the specified file.\\n4 \\\"\\\"\\\"\\n5 with open(filename, 'w') as file:\\n6 file.write('hello')\\n7 \\n8 if __name__ == '__main__':\\n9 write_hello_to_file('output.txt')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\n#!/bin/bash\\n\\n# a) Install dependencies\\n# Since the script does not have any dependencies, we skip this step.\\n\\n# b) Run all necessary parts of the codebase\\npython main.py &\\nwait\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n\\n Information about the codebase:\\n\\n```\\nFile: main.py\\n1 def calculate_and_print_sum(a, b):\\n2 \\\"\\\"\\\"Calculate the sum of two numbers and print the result.\\\"\\\"\\\"\\n3 result = a + b\\n4 print(result)\\n5 \\n6 if __name__ == \\\"__main__\\\":\\n7 calculate_and_print_sum(4, 4)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n\\n Information about the codebase:\\n\\n```\\nFile: main.py\\n1 def calculate_and_print_sum(a, b):\\n2 \\\"\\\"\\\"Calculate the sum of two numbers and print the result.\\\"\\\"\\\"\\n3 result = a + b\\n4 print(result)\\n5 \\n6 if __name__ == \\\"__main__\\\":\\n7 calculate_and_print_sum(4, 4)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\n#!/bin/sh\\n\\n# a) Install dependencies (none required as per requirements.txt, but this is how you would do it)\\n# pip install -r requirements.txt\\n\\n# b) Run the main.py script\\npython main.py &\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"promptInformation about the codebase:\\n\\n```\\nFile: main.py\\n1 def calculate_and_print_sum(a, b):\\n2 \\\"\\\"\\\"Calculate the sum of two numbers and print the result.\\\"\\\"\\\"\\n3 result = a + b\\n4 print(result)\\n5 \\n6 if __name__ == \\\"__main__\\\":\\n7 calculate_and_print_sum(4, 4)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"promptInformation about the codebase:\\n\\n```\\nFile: main.py\\n1 def calculate_and_print_sum(a, b):\\n2 \\\"\\\"\\\"Calculate the sum of two numbers and print the result.\\\"\\\"\\\"\\n3 result = a + b\\n4 print(result)\\n5 \\n6 if __name__ == \\\"__main__\\\":\\n7 calculate_and_print_sum(4, 4)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\npython main.py\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n \\nInformation about the codebase:\\n\\n```\\nFile: main.py\\n1 def write_hello_world_to_file(filename):\\n2 \\\"\\\"\\\"\\n3 Writes 'Hello World!' to the specified file.\\n4 \\n5 :param filename: The name of the file to write to.\\n6 \\\"\\\"\\\"\\n7 with open(filename, 'w') as file:\\n8 file.write('Hello World!')\\n9 \\n10 if __name__ == \\\"__main__\\\":\\n11 output_filename = 'output.txt'\\n12 write_hello_world_to_file(output_filename)\\n\\nFile: requirements.txt\\n1 # No external dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n \\nInformation about the codebase:\\n\\n```\\nFile: main.py\\n1 def write_hello_world_to_file(filename):\\n2 \\\"\\\"\\\"\\n3 Writes 'Hello World!' to the specified file.\\n4 \\n5 :param filename: The name of the file to write to.\\n6 \\\"\\\"\\\"\\n7 with open(filename, 'w') as file:\\n8 file.write('Hello World!')\\n9 \\n10 if __name__ == \\\"__main__\\\":\\n11 output_filename = 'output.txt'\\n12 write_hello_world_to_file(output_filename)\\n\\nFile: requirements.txt\\n1 # No external dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\n#!/bin/bash\\n\\n# a) Install dependencies (none required as per requirements.txt, but this is how you would do it)\\n# pip install -r requirements.txt\\n\\n# b) Run the main.py script\\npython main.py &\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n \\nInformation about the codebase:\\n\\n```\\nFile: hello_world.py\\n1 with open('output.txt', 'w') as file:\\n2 file.write('Hello World!\\\\n')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n \\nInformation about the codebase:\\n\\n```\\nFile: hello_world.py\\n1 with open('output.txt', 'w') as file:\\n2 file.write('Hello World!\\\\n')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\n#!/bin/bash\\n\\n# a) Install dependencies\\n# There are no external dependencies to install for this Python script.\\n\\n# b) Run the necessary parts of the codebase\\npython hello_world.py &\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n \\nInformation about the codebase:\\n\\n```\\nFile: main.py\\n1 def write_hello_world(file_path):\\n2 with open(file_path, 'w') as file:\\n3 file.write(\\\"Hello World!\\\\n\\\")\\n4 \\n5 if __name__ == \\\"__main__\\\":\\n6 write_hello_world('output.txt')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n \\nInformation about the codebase:\\n\\n```\\nFile: main.py\\n1 def write_hello_world(file_path):\\n2 with open(file_path, 'w') as file:\\n3 file.write(\\\"Hello World!\\\\n\\\")\\n4 \\n5 if __name__ == \\\"__main__\\\":\\n6 write_hello_world('output.txt')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\n#!/bin/bash\\n\\n# a) Install dependencies\\n# Assuming Python3 is already installed and there are no external dependencies for this script\\n# If there were a requirements.txt file, you would typically run:\\n# python3 -m pip install --user -r requirements.txt\\n\\n# b) Run the codebase\\npython3 main.py &\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n \\nInformation about the codebase:\\n\\n```\\nFile: main.py\\n1 from file_writer import write_to_file\\n2 \\n3 def main():\\n4 # The text to be written to the file\\n5 text_to_write = \\\"hello\\\"\\n6 # The filename of the file to write to\\n7 output_filename = \\\"output.txt\\\"\\n8 # Write the text to the file\\n9 write_to_file(output_filename, text_to_write)\\n10 \\n11 if __name__ == \\\"__main__\\\":\\n12 main()\\n\\nFile: file_writer.py\\n1 def write_to_file(filename, text):\\n2 \\\"\\\"\\\"\\n3 Writes the given text to a file with the specified filename.\\n4 \\\"\\\"\\\"\\n5 with open(filename, 'w') as file:\\n6 file.write(text)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n \\nInformation about the codebase:\\n\\n```\\nFile: main.py\\n1 from file_writer import write_to_file\\n2 \\n3 def main():\\n4 # The text to be written to the file\\n5 text_to_write = \\\"hello\\\"\\n6 # The filename of the file to write to\\n7 output_filename = \\\"output.txt\\\"\\n8 # Write the text to the file\\n9 write_to_file(output_filename, text_to_write)\\n10 \\n11 if __name__ == \\\"__main__\\\":\\n12 main()\\n\\nFile: file_writer.py\\n1 def write_to_file(filename, text):\\n2 \\\"\\\"\\\"\\n3 Writes the given text to a file with the specified filename.\\n4 \\\"\\\"\\\"\\n5 with open(filename, 'w') as file:\\n6 file.write(text)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\n# a) Since there are no dependencies required, this step is essentially a no-op.\\n# However, if there were dependencies, they would be installed like this:\\n# python3 -m pip install --user -r requirements.txt\\n\\n# b) Run the main.py script\\npython3 main.py\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n \\nInformation about the codebase:\\n\\n```\\nFile: write_hello.py\\n1 # This Python script writes 'hello' to a file called 'output.txt'\\n2 \\n3 with open('output.txt', 'w') as file:\\n4 file.write('hello')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n \\nInformation about the codebase:\\n\\n```\\nFile: write_hello.py\\n1 # This Python script writes 'hello' to a file called 'output.txt'\\n2 \\n3 with open('output.txt', 'w') as file:\\n4 file.write('hello')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\n#!/bin/bash\\n\\n# a) Install dependencies\\n# There are no dependencies to install for this simple Python script\\n\\n# b) Run the Python script\\npython write_hello.py &\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n \\nInformation about the codebase:\\n\\n```\\nFile: main.py\\n1 def write_hello_to_file(filename):\\n2 \\\"\\\"\\\"\\n3 Writes 'hello' to the specified file.\\n4 \\\"\\\"\\\"\\n5 with open(filename, 'w') as file:\\n6 file.write('hello')\\n7 \\n8 if __name__ == '__main__':\\n9 write_hello_to_file('output.txt')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n \\nInformation about the codebase:\\n\\n```\\nFile: main.py\\n1 def write_hello_to_file(filename):\\n2 \\\"\\\"\\\"\\n3 Writes 'hello' to the specified file.\\n4 \\\"\\\"\\\"\\n5 with open(filename, 'w') as file:\\n6 file.write('hello')\\n7 \\n8 if __name__ == '__main__':\\n9 write_hello_to_file('output.txt')\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\n#!/bin/bash\\n\\n# a) Install dependencies\\n# Assuming Python3 is already installed and there are no external dependencies\\n# for this simple script, we don't need to install anything.\\n\\n# b) Run the codebase\\npython3 main.py &\\nwait\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"prompt\\nInformation about the codebase:\\n\\n```\\nFile: main.py\\n1 def calculate_and_print_sum(a, b):\\n2 \\\"\\\"\\\"Calculate the sum of two numbers and print the result.\\\"\\\"\\\"\\n3 result = a + b\\n4 print(result)\\n5 \\n6 if __name__ == \\\"__main__\\\":\\n7 calculate_and_print_sum(4, 4)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"prompt\\nInformation about the codebase:\\n\\n```\\nFile: main.py\\n1 def calculate_and_print_sum(a, b):\\n2 \\\"\\\"\\\"Calculate the sum of two numbers and print the result.\\\"\\\"\\\"\\n3 result = a + b\\n4 print(result)\\n5 \\n6 if __name__ == \\\"__main__\\\":\\n7 calculate_and_print_sum(4, 4)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\npython main.py\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"make a program that prints the outcome of 4+4\\nInformation about the codebase:\\n\\n```\\nFile: main.py\\n1 def calculate_and_print_sum(a, b):\\n2 \\\"\\\"\\\"Calculate the sum of two numbers and print the result.\\\"\\\"\\\"\\n3 result = a + b\\n4 print(result)\\n5 \\n6 if __name__ == \\\"__main__\\\":\\n7 calculate_and_print_sum(4, 4)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"make a program that prints the outcome of 4+4\\nInformation about the codebase:\\n\\n```\\nFile: main.py\\n1 def calculate_and_print_sum(a, b):\\n2 \\\"\\\"\\\"Calculate the sum of two numbers and print the result.\\\"\\\"\\\"\\n3 result = a + b\\n4 print(result)\\n5 \\n6 if __name__ == \\\"__main__\\\":\\n7 calculate_and_print_sum(4, 4)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\npython main.py\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the correct decisions to make sure we get it right.\\nMake changes to existing code and implement new code in the unified git diff syntax. When implementing new code, First lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nOutput requested code changes and new code in the unified \\\"git diff\\\" syntax. Example:\\n\\n```diff\\n--- example.txt\\n+++ example.txt\\n@@ -6,3 +6,4 @@\\n line content A\\n line content B\\n+ new line added\\n- original line X\\n+ modified line X with changes\\n@@ -26,4 +27,5 @@\\n condition check:\\n- action for condition A\\n+ if certain condition is met:\\n+ alternative action for condition A\\n another condition check:\\n- action for condition B\\n+ modified action for condition B\\n```\\n\\nExample of a git diff creating a new file:\\n\\n```diff\\n--- /dev/null\\n+++ new_file.txt\\n@@ -0,0 +1,3 @@\\n+First example line\\n+\\n+Last example line\\n```\\n-A program will apply the diffs you generate exactly to the code, so diffs must be precise and unambiguous!\\n-Every diff must be fenced with triple backtick ```.\\n-The file names at the beginning of a diff, (lines starting with --- and +++) is the relative path to the file before and after the diff.\\n-LINES TO BE REMOVED (starting with single -) AND LINES TO BE RETAIN (no starting symbol) HAVE TO REPLICATE THE DIFFED HUNK OF THE CODE EXACTLY LINE BY LINE. KEEP THE NUMBER OF RETAIN LINES SMALL IF POSSIBLE.\\n-EACH LINE IN THE SOURCE FILES STARTS WITH A LINE NUMBER, WHICH IS NOT PART OF THE SOURCE CODE. NEVER TRANSFER THESE LINE NUMBERS TO THE DIFF HUNKS.\\n-AVOID STARTING A HUNK WITH AN EMPTY LINE.\\n\\n\\nAs far as compatible with the user request, start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\\nUseful to know:\\nAlmost always put different classes in different files.\\nAlways use the programming language the user asks for.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nAlways add a comment briefly describing the purpose of the function definition.\\nAdd comments explaining very complex bits of logic.\\nAlways follow the best practices for the requested languages for folder/file structure and how to package the project.\\n\\n\\nPython toolbelt preferences:\\n- pytest\\n- dataclasses\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"```\\nFile: main.py\\n1 def write_hello_world_to_file(filename):\\n2 \\\"\\\"\\\"\\n3 Writes 'Hello World!' to the specified file.\\n4 \\n5 :param filename: The name of the file to write to.\\n6 \\\"\\\"\\\"\\n7 with open(filename, 'w') as file:\\n8 file.write('Hello World!')\\n9 \\n10 if __name__ == \\\"__main__\\\":\\n11 output_filename = 'output.txt'\\n12 write_hello_world_to_file(output_filename)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\nFile: run.sh\\n1 python3 main.py\\n2 \\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": [{\"type\": \"text\", \"text\": \"Request: Change the program so that it prints '!dlroW olleH' instead of 'Hello World!'\"}], \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the correct decisions to make sure we get it right.\\nMake changes to existing code and implement new code in the unified git diff syntax. When implementing new code, First lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nOutput requested code changes and new code in the unified \\\"git diff\\\" syntax. Example:\\n\\n```diff\\n--- example.txt\\n+++ example.txt\\n@@ -6,3 +6,4 @@\\n line content A\\n line content B\\n+ new line added\\n- original line X\\n+ modified line X with changes\\n@@ -26,4 +27,5 @@\\n condition check:\\n- action for condition A\\n+ if certain condition is met:\\n+ alternative action for condition A\\n another condition check:\\n- action for condition B\\n+ modified action for condition B\\n```\\n\\nExample of a git diff creating a new file:\\n\\n```diff\\n--- /dev/null\\n+++ new_file.txt\\n@@ -0,0 +1,3 @@\\n+First example line\\n+\\n+Last example line\\n```\\n-A program will apply the diffs you generate exactly to the code, so diffs must be precise and unambiguous!\\n-Every diff must be fenced with triple backtick ```.\\n-The file names at the beginning of a diff, (lines starting with --- and +++) is the relative path to the file before and after the diff.\\n-LINES TO BE REMOVED (starting with single -) AND LINES TO BE RETAIN (no starting symbol) HAVE TO REPLICATE THE DIFFED HUNK OF THE CODE EXACTLY LINE BY LINE. KEEP THE NUMBER OF RETAIN LINES SMALL IF POSSIBLE.\\n-EACH LINE IN THE SOURCE FILES STARTS WITH A LINE NUMBER, WHICH IS NOT PART OF THE SOURCE CODE. NEVER TRANSFER THESE LINE NUMBERS TO THE DIFF HUNKS.\\n-AVOID STARTING A HUNK WITH AN EMPTY LINE.\\n\\n\\nAs far as compatible with the user request, start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\\nUseful to know:\\nAlmost always put different classes in different files.\\nAlways use the programming language the user asks for.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nAlways add a comment briefly describing the purpose of the function definition.\\nAdd comments explaining very complex bits of logic.\\nAlways follow the best practices for the requested languages for folder/file structure and how to package the project.\\n\\n\\nPython toolbelt preferences:\\n- pytest\\n- dataclasses\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"```\\nFile: main.py\\n1 def write_hello_world_to_file(filename):\\n2 \\\"\\\"\\\"\\n3 Writes 'Hello World!' to the specified file.\\n4 \\n5 :param filename: The name of the file to write to.\\n6 \\\"\\\"\\\"\\n7 with open(filename, 'w') as file:\\n8 file.write('Hello World!')\\n9 \\n10 if __name__ == \\\"__main__\\\":\\n11 output_filename = 'output.txt'\\n12 write_hello_world_to_file(output_filename)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\nFile: run.sh\\n1 python3 main.py\\n2 \\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": [{\"type\": \"text\", \"text\": \"Request: Change the program so that it prints '!dlroW olleH' instead of 'Hello World!'\"}], \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```diff\\n--- main.py\\n+++ main.py\\n@@ -7,3 +7,3 @@\\n with open(filename, 'w') as file:\\n- file.write('Hello World!')\\n+ file.write('!dlroW olleH')\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n \\nInformation about the codebase:\\n\\n```\\nFile: main.py\\n1 def write_hello_world_to_file(filename):\\n2 \\\"\\\"\\\"\\n3 Writes 'Hello World!' to the specified file.\\n4 \\n5 :param filename: The name of the file to write to.\\n6 \\\"\\\"\\\"\\n7 with open(filename, 'w') as file:\\n8 file.write('!dlroW olleH')\\n9 \\n10 if __name__ == \\\"__main__\\\":\\n11 output_filename = 'output.txt'\\n12 write_hello_world_to_file(output_filename)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\nFile: run.sh\\n1 python3 main.py\\n2 \\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n \\nInformation about the codebase:\\n\\n```\\nFile: main.py\\n1 def write_hello_world_to_file(filename):\\n2 \\\"\\\"\\\"\\n3 Writes 'Hello World!' to the specified file.\\n4 \\n5 :param filename: The name of the file to write to.\\n6 \\\"\\\"\\\"\\n7 with open(filename, 'w') as file:\\n8 file.write('!dlroW olleH')\\n9 \\n10 if __name__ == \\\"__main__\\\":\\n11 output_filename = 'output.txt'\\n12 write_hello_world_to_file(output_filename)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\nFile: run.sh\\n1 python3 main.py\\n2 \\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\n#!/bin/bash\\n\\n# a) Install dependencies (there are none in this case, but this is how you would do it)\\n# pip install -r requirements.txt\\n\\n# b) Run the necessary parts of the codebase\\nchmod +x run.sh\\n./run.sh &\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the correct decisions to make sure we get it right.\\nMake changes to existing code and implement new code in the unified git diff syntax. When implementing new code, First lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nOutput requested code changes and new code in the unified \\\"git diff\\\" syntax. Example:\\n\\n```diff\\n--- example.txt\\n+++ example.txt\\n@@ -6,3 +6,4 @@\\n line content A\\n line content B\\n+ new line added\\n- original line X\\n+ modified line X with changes\\n@@ -26,4 +27,5 @@\\n condition check:\\n- action for condition A\\n+ if certain condition is met:\\n+ alternative action for condition A\\n another condition check:\\n- action for condition B\\n+ modified action for condition B\\n```\\n\\nExample of a git diff creating a new file:\\n\\n```diff\\n--- /dev/null\\n+++ new_file.txt\\n@@ -0,0 +1,3 @@\\n+First example line\\n+\\n+Last example line\\n```\\n-A program will apply the diffs you generate exactly to the code, so diffs must be precise and unambiguous!\\n-Every diff must be fenced with triple backtick ```.\\n-The file names at the beginning of a diff, (lines starting with --- and +++) is the relative path to the file before and after the diff.\\n-LINES TO BE REMOVED (starting with single -) AND LINES TO BE RETAIN (no starting symbol) HAVE TO REPLICATE THE DIFFED HUNK OF THE CODE EXACTLY LINE BY LINE. KEEP THE NUMBER OF RETAIN LINES SMALL IF POSSIBLE.\\n-EACH LINE IN THE SOURCE FILES STARTS WITH A LINE NUMBER, WHICH IS NOT PART OF THE SOURCE CODE. NEVER TRANSFER THESE LINE NUMBERS TO THE DIFF HUNKS.\\n-AVOID STARTING A HUNK WITH AN EMPTY LINE.\\n\\n\\nAs far as compatible with the user request, start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\\nUseful to know:\\nAlmost always put different classes in different files.\\nAlways use the programming language the user asks for.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nAlways add a comment briefly describing the purpose of the function definition.\\nAdd comments explaining very complex bits of logic.\\nAlways follow the best practices for the requested languages for folder/file structure and how to package the project.\\n\\n\\nPython toolbelt preferences:\\n- pytest\\n- dataclasses\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"```\\nFile: main.py\\n1 The program will be written in this file\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": [{\"type\": \"text\", \"text\": \"Request: Make a python program that writes 'hello' to a file called 'output.txt'\"}], \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the correct decisions to make sure we get it right.\\nMake changes to existing code and implement new code in the unified git diff syntax. When implementing new code, First lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nOutput requested code changes and new code in the unified \\\"git diff\\\" syntax. Example:\\n\\n```diff\\n--- example.txt\\n+++ example.txt\\n@@ -6,3 +6,4 @@\\n line content A\\n line content B\\n+ new line added\\n- original line X\\n+ modified line X with changes\\n@@ -26,4 +27,5 @@\\n condition check:\\n- action for condition A\\n+ if certain condition is met:\\n+ alternative action for condition A\\n another condition check:\\n- action for condition B\\n+ modified action for condition B\\n```\\n\\nExample of a git diff creating a new file:\\n\\n```diff\\n--- /dev/null\\n+++ new_file.txt\\n@@ -0,0 +1,3 @@\\n+First example line\\n+\\n+Last example line\\n```\\n-A program will apply the diffs you generate exactly to the code, so diffs must be precise and unambiguous!\\n-Every diff must be fenced with triple backtick ```.\\n-The file names at the beginning of a diff, (lines starting with --- and +++) is the relative path to the file before and after the diff.\\n-LINES TO BE REMOVED (starting with single -) AND LINES TO BE RETAIN (no starting symbol) HAVE TO REPLICATE THE DIFFED HUNK OF THE CODE EXACTLY LINE BY LINE. KEEP THE NUMBER OF RETAIN LINES SMALL IF POSSIBLE.\\n-EACH LINE IN THE SOURCE FILES STARTS WITH A LINE NUMBER, WHICH IS NOT PART OF THE SOURCE CODE. NEVER TRANSFER THESE LINE NUMBERS TO THE DIFF HUNKS.\\n-AVOID STARTING A HUNK WITH AN EMPTY LINE.\\n\\n\\nAs far as compatible with the user request, start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\\nUseful to know:\\nAlmost always put different classes in different files.\\nAlways use the programming language the user asks for.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nAlways add a comment briefly describing the purpose of the function definition.\\nAdd comments explaining very complex bits of logic.\\nAlways follow the best practices for the requested languages for folder/file structure and how to package the project.\\n\\n\\nPython toolbelt preferences:\\n- pytest\\n- dataclasses\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"```\\nFile: main.py\\n1 The program will be written in this file\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": [{\"type\": \"text\", \"text\": \"Request: Make a python program that writes 'hello' to a file called 'output.txt'\"}], \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"To create a Python program that writes 'hello' to a file called 'output.txt', we will need to perform the following steps:\\n\\n1. Open the file 'output.txt' in write mode.\\n2. Write the string 'hello' to the file.\\n3. Close the file to ensure the data is written and the file is not left open.\\n\\nHere is the implementation in the `main.py` file:\\n\\n```diff\\n--- /dev/null\\n+++ main.py\\n@@ -0,0 +1,8 @@\\n+# main.py\\n+# This program writes 'hello' to a file called 'output.txt'\\n+\\n+with open('output.txt', 'w') as file:\\n+ file.write('hello')\\n+\\n+# This concludes the writing operation, 'output.txt' should now contain the word 'hello'\\n+\\n```\\n\\nThis concludes the implementation of the requested Python program.\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n \\nInformation about the codebase:\\n\\n```\\nFile: main.py\\n1 def calculate_and_print_sum(a, b):\\n2 \\\"\\\"\\\"Calculate the sum of two numbers and print the result.\\\"\\\"\\\"\\n3 result = a + b\\n4 print(result)\\n5 \\n6 if __name__ == \\\"__main__\\\":\\n7 calculate_and_print_sum(4, 4)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get information about a codebase that is currently on disk in the current folder.\\nThe user will ask you to write a script that runs the code in a specific way.\\nYou will answer with code blocks that include all the necessary terminal commands.\\nDo not install globally. Do not use sudo.\\nDo not explain the code, just give the commands.\\nDo not use placeholders, use example values (like . for a folder argument) if necessary.\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"\\n Make a unix script that\\n a) installs dependencies\\n b) runs all necessary parts of the codebase (in parallel if necessary)\\n \\nInformation about the codebase:\\n\\n```\\nFile: main.py\\n1 def calculate_and_print_sum(a, b):\\n2 \\\"\\\"\\\"Calculate the sum of two numbers and print the result.\\\"\\\"\\\"\\n3 result = a + b\\n4 print(result)\\n5 \\n6 if __name__ == \\\"__main__\\\":\\n7 calculate_and_print_sum(4, 4)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```sh\\n#!/bin/bash\\n\\n# a) Install dependencies (none required in this case, but pip install command provided for demonstration)\\n# pip install -r requirements.txt\\n\\n# b) Run the main.py script\\npython main.py &\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]", "[{\"type\": \"system\", \"data\": {\"content\": \"You will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the correct decisions to make sure we get it right.\\nMake changes to existing code and implement new code in the unified git diff syntax. When implementing new code, First lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nOutput requested code changes and new code in the unified \\\"git diff\\\" syntax. Example:\\n\\n```diff\\n--- example.txt\\n+++ example.txt\\n@@ -6,3 +6,4 @@\\n line content A\\n line content B\\n+ new line added\\n- original line X\\n+ modified line X with changes\\n@@ -26,4 +27,5 @@\\n condition check:\\n- action for condition A\\n+ if certain condition is met:\\n+ alternative action for condition A\\n another condition check:\\n- action for condition B\\n+ modified action for condition B\\n```\\n\\nExample of a git diff creating a new file:\\n\\n```diff\\n--- /dev/null\\n+++ new_file.txt\\n@@ -0,0 +1,3 @@\\n+First example line\\n+\\n+Last example line\\n```\\n-A program will apply the diffs you generate exactly to the code, so diffs must be precise and unambiguous!\\n-Every diff must be fenced with triple backtick ```.\\n-The file names at the beginning of a diff, (lines starting with --- and +++) is the relative path to the file before and after the diff.\\n-LINES TO BE REMOVED (starting with single -) AND LINES TO BE RETAIN (no starting symbol) HAVE TO REPLICATE THE DIFFED HUNK OF THE CODE EXACTLY LINE BY LINE. KEEP THE NUMBER OF RETAIN LINES SMALL IF POSSIBLE.\\n-EACH LINE IN THE SOURCE FILES STARTS WITH A LINE NUMBER, WHICH IS NOT PART OF THE SOURCE CODE. NEVER TRANSFER THESE LINE NUMBERS TO THE DIFF HUNKS.\\n-AVOID STARTING A HUNK WITH AN EMPTY LINE.\\n\\n\\nAs far as compatible with the user request, start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\\nUseful to know:\\nAlmost always put different classes in different files.\\nAlways use the programming language the user asks for.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nAlways add a comment briefly describing the purpose of the function definition.\\nAdd comments explaining very complex bits of logic.\\nAlways follow the best practices for the requested languages for folder/file structure and how to package the project.\\n\\n\\nPython toolbelt preferences:\\n- pytest\\n- dataclasses\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"```\\nFile: main.py\\n1 def write_hello_world_to_file(filename):\\n2 \\\"\\\"\\\"\\n3 Writes 'Hello World!' to the specified file.\\n4 \\n5 :param filename: The name of the file to write to.\\n6 \\\"\\\"\\\"\\n7 with open(filename, 'w') as file:\\n8 file.write('Hello World!')\\n9 \\n10 if __name__ == \\\"__main__\\\":\\n11 output_filename = 'output.txt'\\n12 write_hello_world_to_file(output_filename)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\nFile: run.sh\\n1 python3 main.py\\n2 \\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": [{\"type\": \"text\", \"text\": \"Request: Change the program so that it prints '!dlroW olleH' instead of 'Hello World!' \"}], \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}]": "[{\"type\": \"system\", \"data\": {\"content\": \"You will get instructions for code to write.\\nYou will write a very long answer. Make sure that every detail of the architecture is, in the end, implemented as code.\\nThink step by step and reason yourself to the correct decisions to make sure we get it right.\\nMake changes to existing code and implement new code in the unified git diff syntax. When implementing new code, First lay out the names of the core classes, functions, methods that will be necessary, As well as a quick comment on their purpose.\\n\\nYou will output the content of each file necessary to achieve the goal, including ALL code.\\nOutput requested code changes and new code in the unified \\\"git diff\\\" syntax. Example:\\n\\n```diff\\n--- example.txt\\n+++ example.txt\\n@@ -6,3 +6,4 @@\\n line content A\\n line content B\\n+ new line added\\n- original line X\\n+ modified line X with changes\\n@@ -26,4 +27,5 @@\\n condition check:\\n- action for condition A\\n+ if certain condition is met:\\n+ alternative action for condition A\\n another condition check:\\n- action for condition B\\n+ modified action for condition B\\n```\\n\\nExample of a git diff creating a new file:\\n\\n```diff\\n--- /dev/null\\n+++ new_file.txt\\n@@ -0,0 +1,3 @@\\n+First example line\\n+\\n+Last example line\\n```\\n-A program will apply the diffs you generate exactly to the code, so diffs must be precise and unambiguous!\\n-Every diff must be fenced with triple backtick ```.\\n-The file names at the beginning of a diff, (lines starting with --- and +++) is the relative path to the file before and after the diff.\\n-LINES TO BE REMOVED (starting with single -) AND LINES TO BE RETAIN (no starting symbol) HAVE TO REPLICATE THE DIFFED HUNK OF THE CODE EXACTLY LINE BY LINE. KEEP THE NUMBER OF RETAIN LINES SMALL IF POSSIBLE.\\n-EACH LINE IN THE SOURCE FILES STARTS WITH A LINE NUMBER, WHICH IS NOT PART OF THE SOURCE CODE. NEVER TRANSFER THESE LINE NUMBERS TO THE DIFF HUNKS.\\n-AVOID STARTING A HUNK WITH AN EMPTY LINE.\\n\\n\\nAs far as compatible with the user request, start with the \\\"entrypoint\\\" file, then go to the ones that are imported by that file, and so on.\\nPlease note that the code should be fully functional. No placeholders.\\n\\nFollow a language and framework appropriate best practice file naming convention.\\nMake sure that files contain all imports, types etc. The code should be fully functional. Make sure that code in different files are compatible with each other.\\nEnsure to implement all code, if you are unsure, write a plausible implementation.\\nInclude module dependency or package manager dependency definition file.\\nBefore you finish, double check that all parts of the architecture is present in the files.\\n\\nWhen you are done, write finish with \\\"this concludes a fully working implementation\\\".\\n\\nUseful to know:\\nAlmost always put different classes in different files.\\nAlways use the programming language the user asks for.\\nFor Python, you always create an appropriate requirements.txt file.\\nFor NodeJS, you always create an appropriate package.json file.\\nAlways add a comment briefly describing the purpose of the function definition.\\nAdd comments explaining very complex bits of logic.\\nAlways follow the best practices for the requested languages for folder/file structure and how to package the project.\\n\\n\\nPython toolbelt preferences:\\n- pytest\\n- dataclasses\\n\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"system\", \"name\": null, \"id\": null}}, {\"type\": \"human\", \"data\": {\"content\": \"```\\nFile: main.py\\n1 def write_hello_world_to_file(filename):\\n2 \\\"\\\"\\\"\\n3 Writes 'Hello World!' to the specified file.\\n4 \\n5 :param filename: The name of the file to write to.\\n6 \\\"\\\"\\\"\\n7 with open(filename, 'w') as file:\\n8 file.write('Hello World!')\\n9 \\n10 if __name__ == \\\"__main__\\\":\\n11 output_filename = 'output.txt'\\n12 write_hello_world_to_file(output_filename)\\n\\nFile: requirements.txt\\n1 # No dependencies required\\n\\nFile: run.sh\\n1 python3 main.py\\n2 \\n\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"human\", \"data\": {\"content\": [{\"type\": \"text\", \"text\": \"Request: Change the program so that it prints '!dlroW olleH' instead of 'Hello World!' \"}], \"additional_kwargs\": {}, \"response_metadata\": {}, \"type\": \"human\", \"name\": null, \"id\": null, \"example\": false}}, {\"type\": \"ai\", \"data\": {\"content\": \"```diff\\n--- main.py\\n+++ main.py\\n@@ -7,3 +7,3 @@\\n with open(filename, 'w') as file:\\n- file.write('Hello World!')\\n+ file.write('!dlroW olleH')\\n```\", \"additional_kwargs\": {}, \"response_metadata\": {\"token_usage\": {\"completion_tokens\": 54, \"prompt_tokens\": 885, \"total_tokens\": 939}, \"model_name\": \"gpt-4-1106-preview\", \"system_fingerprint\": \"fp_76413ed44d\", \"finish_reason\": \"stop\", \"logprobs\": null}, \"type\": \"ai\", \"name\": null, \"id\": null, \"example\": false}}]"} ================================================ FILE: tests/applications/__init__.py ================================================ ================================================ FILE: tests/applications/cli/__init__.py ================================================ ================================================ FILE: tests/applications/cli/test_cli_agent.py ================================================ import os import tempfile import pytest from langchain.schema import AIMessage from gpt_engineer.applications.cli.cli_agent import CliAgent from gpt_engineer.core.default.disk_execution_env import DiskExecutionEnv from gpt_engineer.core.default.disk_memory import DiskMemory # from gpt_engineer.core.default.git_version_manager import GitVersionManager from gpt_engineer.core.default.paths import ENTRYPOINT_FILE, memory_path from gpt_engineer.core.files_dict import FilesDict from gpt_engineer.core.prompt import Prompt from gpt_engineer.tools.custom_steps import clarified_gen, lite_gen from tests.mock_ai import MockAI def test_init_standard_config(monkeypatch): monkeypatch.setattr("builtins.input", lambda _: "y") temp_dir = tempfile.mkdtemp() memory = DiskMemory(memory_path(temp_dir)) execution_env = DiskExecutionEnv() mock_ai = MockAI( [ AIMessage( "hello_world.py\n```\nwith open('output.txt', 'w') as file:\n file.write('Hello World!')\n```" ), AIMessage("```run.sh\npython3 hello_world.py\n```"), ], ) cli_agent = CliAgent.with_default_config(memory, execution_env, ai=mock_ai) outfile = "output.txt" os.path.join(temp_dir, outfile) code = cli_agent.init( Prompt( f"Make a program that prints 'Hello World!' to a file called '{outfile}'" ) ) env = DiskExecutionEnv() env.upload(code).run(f"bash {ENTRYPOINT_FILE}") code = env.download() assert outfile in code assert code[outfile] == "Hello World!" def test_init_lite_config(monkeypatch): monkeypatch.setattr("builtins.input", lambda _: "y") temp_dir = tempfile.mkdtemp() memory = DiskMemory(memory_path(temp_dir)) # version_manager = GitVersionManager(temp_dir) execution_env = DiskExecutionEnv() mock_ai = MockAI( [ AIMessage( "hello_world.py\n```\nwith open('output.txt', 'w') as file:\n file.write('Hello World!')\n```" ), AIMessage("```run.sh\npython3 hello_world.py\n```"), ], ) cli_agent = CliAgent.with_default_config( memory, execution_env, ai=mock_ai, code_gen_fn=lite_gen ) outfile = "output.txt" os.path.join(temp_dir, outfile) code = cli_agent.init( Prompt( f"Make a program that prints 'Hello World!' to a file called '{outfile}'" ) ) env = DiskExecutionEnv() env.upload(code).run(f"bash {ENTRYPOINT_FILE}") code = env.download() assert outfile in code assert code[outfile].strip() == "Hello World!" def test_init_clarified_gen_config(monkeypatch): monkeypatch.setattr("builtins.input", lambda _: "y") temp_dir = tempfile.mkdtemp() memory = DiskMemory(memory_path(temp_dir)) execution_env = DiskExecutionEnv() mock_ai = MockAI( [ AIMessage("nothing to clarify"), AIMessage( "hello_world.py\n```\nwith open('output.txt', 'w') as file:\n file.write('Hello World!')\n```" ), AIMessage("```run.sh\npython3 hello_world.py\n```"), ], ) cli_agent = CliAgent.with_default_config( memory, execution_env, ai=mock_ai, code_gen_fn=clarified_gen ) outfile = "output.txt" code = cli_agent.init( Prompt( f"Make a program that prints 'Hello World!' to a file called '{outfile} either using python or javascript'" ) ) env = DiskExecutionEnv() env.upload(code).run(f"bash {ENTRYPOINT_FILE}") code = env.download() assert outfile in code assert code[outfile].strip() == "Hello World!" def test_improve_standard_config(monkeypatch): monkeypatch.setattr("builtins.input", lambda _: "y") temp_dir = tempfile.mkdtemp() code = FilesDict( { "main.py": "def write_hello_world_to_file(filename):\n \"\"\"\n Writes 'Hello World!' to the specified file.\n \n :param filename: The name of the file to write to.\n \"\"\"\n with open(filename, 'w') as file:\n file.write('Hello World!')\n\nif __name__ == \"__main__\":\n output_filename = 'output.txt'\n write_hello_world_to_file(output_filename)", "requirements.txt": "# No dependencies required", "run.sh": "python3 main.py\n", } ) memory = DiskMemory(memory_path(temp_dir)) # version_manager = GitVersionManager(temp_dir) execution_env = DiskExecutionEnv() mock_ai = MockAI( [ AIMessage( "```diff\n--- main.py\n+++ main.py\n@@ -7,3 +7,3 @@\n with open(filename, 'w') as file:\n- file.write('Hello World!')\n+ file.write('!dlroW olleH')\n```" ) ] ) cli_agent = CliAgent.with_default_config(memory, execution_env, ai=mock_ai) code = cli_agent.improve( code, Prompt( "Change the program so that it prints '!dlroW olleH' instead of 'Hello World!'" ), ) env = DiskExecutionEnv() env.upload(code).run(f"bash {ENTRYPOINT_FILE}") code = env.download() outfile = "output.txt" assert outfile in code assert code[outfile] == "!dlroW olleH" if __name__ == "__main__": pytest.main() ================================================ FILE: tests/applications/cli/test_collect.py ================================================ """ Tests the collect_learnings function in the cli/collect module. """ import pytest # def test_collect_learnings(monkeypatch): # monkeypatch.setattr(rudder_analytics, "track", MagicMock()) # # model = "test_model" # temperature = 0.5 # steps = [simple_gen] # dbs = FileRepositories( # OnDiskRepository("/tmp"), # OnDiskRepository("/tmp"), # OnDiskRepository("/tmp"), # OnDiskRepository("/tmp"), # OnDiskRepository("/tmp"), # OnDiskRepository("/tmp"), # OnDiskRepository("/tmp"), # ) # dbs.input = { # "prompt": "test prompt\n with newlines", # "feedback": "test feedback", # } # code = "this is output\n\nit contains code" # dbs.logs = {steps[0].__name__: json.dumps([{"role": "system", "content": code}])} # dbs.memory = {"all_output.txt": "test workspace\n" + code} # # collect_learnings(model, temperature, steps, dbs) # # learnings = extract_learning( # model, temperature, steps, dbs, steps_file_hash=steps_file_hash() # ) # assert rudder_analytics.track.call_count == 1 # assert rudder_analytics.track.call_args[1]["event"] == "learning" # a = { # k: v # for k, v in rudder_analytics.track.call_args[1]["properties"].items() # if k != "timestamp" # } # b = {k: v for k, v in learnings.to_dict().items() if k != "timestamp"} # assert a == b # # assert json.dumps(code) in learnings.logs # assert code in learnings.workspace if __name__ == "__main__": pytest.main(["-v"]) ================================================ FILE: tests/applications/cli/test_collection_consent.py ================================================ """ Tests for the revised data collection consent mechanism in the cli/learning module. """ from pathlib import Path from unittest.mock import patch import pytest from gpt_engineer.applications.cli.learning import ( ask_collection_consent, check_collection_consent, ) # Use a fixture to clean up created files after each test @pytest.fixture def cleanup(): yield if Path(".gpte_consent").exists(): Path(".gpte_consent").unlink() """ Test the following 4 scenarios for check_collection_consent(): * The .gpte_consent file exists and its content is "true". * The .gpte_consent file exists but its content is not "true". * The .gpte_consent file does not exist and the user gives consent when asked. * The .gpte_consent file does not exist and the user does not give consent when asked. """ def test_check_consent_file_exists_and_true(cleanup): Path(".gpte_consent").write_text("true") assert check_collection_consent() is True def test_check_consent_file_exists_and_false(cleanup): Path(".gpte_consent").write_text("false") with patch("builtins.input", side_effect=["n"]): assert check_collection_consent() is False def test_check_consent_file_not_exists_and_user_says_yes(cleanup): with patch("builtins.input", side_effect=["y"]): assert check_collection_consent() is True assert Path(".gpte_consent").exists() assert Path(".gpte_consent").read_text() == "true" def test_check_consent_file_not_exists_and_user_says_no(cleanup): with patch("builtins.input", side_effect=["n"]): assert check_collection_consent() is False assert not Path(".gpte_consent").exists() """ Test the following 4 scenarios for ask_collection_consent(): 1. The user immediately gives consent with "y": * The .gpte_consent file is created with content "true". * The function returns True. 2. The user immediately denies consent with "n": * The .gpte_consent file is not created. * The function returns False. 3. The user first provides an invalid response, then gives consent with "y": * The user is re-prompted after the invalid input. * The .gpte_consent file is created with content "true". * The function returns True. 4. The user first provides an invalid response, then denies consent with "n": * The user is re-prompted after the invalid input. * The .gpte_consent file is not created. * The function returns False. """ def test_ask_collection_consent_yes(cleanup): with patch("builtins.input", side_effect=["y"]): result = ask_collection_consent() assert Path(".gpte_consent").exists() assert Path(".gpte_consent").read_text() == "true" assert result is True def test_ask_collection_consent_no(cleanup): with patch("builtins.input", side_effect=["n"]): result = ask_collection_consent() assert not Path(".gpte_consent").exists() assert result is False def test_ask_collection_consent_invalid_then_yes(cleanup): with patch("builtins.input", side_effect=["invalid", "y"]): result = ask_collection_consent() assert Path(".gpte_consent").exists() assert Path(".gpte_consent").read_text() == "true" assert result is True def test_ask_collection_consent_invalid_then_no(cleanup): with patch("builtins.input", side_effect=["invalid", "n"]): result = ask_collection_consent() assert not Path(".gpte_consent").exists() assert result is False ================================================ FILE: tests/applications/cli/test_learning.py ================================================ from unittest import mock from gpt_engineer.applications.cli import learning from gpt_engineer.applications.cli.learning import Learning from gpt_engineer.core.default.disk_memory import DiskMemory from gpt_engineer.core.prompt import Prompt def test_human_review_input_no_concent_returns_none(): with mock.patch.object(learning, "check_collection_consent", return_value=False): result = learning.human_review_input() assert result is None def test_human_review_input_consent_code_ran_no_comments(): with ( mock.patch.object(learning, "check_collection_consent", return_value=True), mock.patch("builtins.input", return_value="y"), ): result = learning.human_review_input() assert result.raw == "y, y, " assert result.ran is True assert result.works is None assert result.comments == "" def test_human_review_input_consent_code_ran_not_perfect_but_useful_no_comments(): with ( mock.patch.object(learning, "check_collection_consent", return_value=True), mock.patch("builtins.input", side_effect=["y", "n", "y", ""]), ): result = learning.human_review_input() assert result.raw == "y, n, y" assert result.ran is True assert result.works is True assert result.comments == "" def test_check_collection_consent_yes(): gpte_consent_mock = mock.Mock() gpte_consent_mock.exists.return_value = True gpte_consent_mock.read_text.return_value = "true" with mock.patch.object(learning, "Path", return_value=gpte_consent_mock): result = learning.check_collection_consent() assert result is True def test_check_collection_consent_no_ask_collection_consent(): with mock.patch.object(learning, "Path") as gpte_consent_mock: gpte_consent_mock.exists.return_value = True gpte_consent_mock.read_text.return_value = "false" with mock.patch.object(learning, "ask_collection_consent", return_value=True): result = learning.check_collection_consent() assert result is True def test_ask_collection_consent_yes(): with mock.patch("builtins.input", return_value="y"): result = learning.ask_collection_consent() assert result is True def test_ask_collection_consent_no(): with mock.patch("builtins.input", return_value="n"): result = learning.ask_collection_consent() assert result is False def test_extract_learning(): review = learning.Review( raw="y, n, y", ran=True, works=True, perfect=False, comments="The code is not perfect", ) memory = mock.Mock(spec=DiskMemory) memory.to_json.return_value = {"prompt": "prompt"} result = learning.extract_learning( Prompt("prompt"), "model_name", 0.01, ("prompt_tokens", "completion_tokens"), memory, review, ) assert isinstance(result, Learning) def test_get_session(): with mock.patch.object(learning, "Path") as path_mock: # can be better tested with pyfakefs. path_mock.return_value.__truediv__.return_value.exists.return_value = False with mock.patch.object(learning, "random") as random_mock: random_mock.randint.return_value = 42 result = learning.get_session() assert result == "42" ================================================ FILE: tests/applications/cli/test_main.py ================================================ import dataclasses import functools import inspect import os import shutil import tempfile from argparse import Namespace from unittest.mock import patch import pytest import typer import gpt_engineer.applications.cli.main as main from gpt_engineer.applications.cli.main import load_prompt from gpt_engineer.core.default.disk_memory import DiskMemory from gpt_engineer.core.prompt import Prompt @functools.wraps(dataclasses.make_dataclass) def dcommand(typer_f, **kwargs): required = True def field_desc(name, param): nonlocal required t = param.annotation or "typing.Any" if param.default.default is not ...: required = False return name, t, dataclasses.field(default=param.default.default) if not required: raise ValueError("Required value after optional") return name, t kwargs.setdefault("cls_name", typer_f.__name__) params = inspect.signature(typer_f).parameters kwargs["fields"] = [field_desc(k, v) for k, v in params.items()] @functools.wraps(typer_f) def dcommand_decorator(function_or_class): assert callable(function_or_class) ka = dict(kwargs) ns = Namespace(**(ka.pop("namespace", None) or {})) if isinstance(function_or_class, type): ka["bases"] = *ka.get("bases", ()), function_or_class else: ns.__call__ = function_or_class ka["namespace"] = vars(ns) return dataclasses.make_dataclass(**ka) return dcommand_decorator @dcommand(main.main) class DefaultArgumentsMain: def __call__(self): attribute_dict = vars(self) main.main(**attribute_dict) def input_generator(): yield "y" # First response while True: yield "n" # Subsequent responses prompt_text = "Make a python program that writes 'hello' to a file called 'output.txt'" class TestMain: # Runs gpt-engineer cli interface for many parameter configurations, BUT DOES NOT CODEGEN! Only testing cli. def test_default_settings_generate_project(self, tmp_path, monkeypatch): p = tmp_path / "projects/example" p.mkdir(parents=True) (p / "prompt").write_text(prompt_text) args = DefaultArgumentsMain(str(p), llm_via_clipboard=True, no_execution=True) args() # Runs gpt-engineer with improve mode and improves an existing project in the specified path. def test_improve_existing_project(self, tmp_path, monkeypatch): p = tmp_path / "projects/example" p.mkdir(parents=True) (p / "prompt").write_text(prompt_text) args = DefaultArgumentsMain( str(p), improve_mode=True, llm_via_clipboard=True, no_execution=True ) args() # Runs gpt-engineer with improve mode and improves an existing project in the specified path, with skip_file_selection def test_improve_existing_project_skip_file_selection(self, tmp_path, monkeypatch): p = tmp_path / "projects/example" p.mkdir(parents=True) (p / "prompt").write_text(prompt_text) args = DefaultArgumentsMain( str(p), improve_mode=True, llm_via_clipboard=True, no_execution=True, skip_file_selection=True, ) args() assert args.skip_file_selection, "Skip_file_selection not set" # Runs gpt-engineer with improve mode and improves an existing project in the specified path, with skip_file_selection def test_improve_existing_project_diff_timeout(self, tmp_path, monkeypatch): p = tmp_path / "projects/example" p.mkdir(parents=True) (p / "prompt").write_text(prompt_text) args = DefaultArgumentsMain( str(p), improve_mode=True, llm_via_clipboard=True, no_execution=True, diff_timeout=99, ) args() assert args.diff_timeout == 99, "Diff timeout not set" # def improve_generator(): # yield "y" # while True: # yield "n" # Subsequent responses # # gen = improve_generator() # monkeypatch.setattr("builtins.input", lambda _: next(gen)) # p = tmp_path / "projects/example" # p.mkdir(parents=True) # (p / "prompt").write_text(prompt_text) # (p / "main.py").write_text("The program will be written in this file") # meta_p = p / META_DATA_REL_PATH # meta_p.mkdir(parents=True) # (meta_p / "file_selection.toml").write_text( # """ # [files] # "main.py" = "selected" # """ # ) # os.environ["GPTE_TEST_MODE"] = "True" # simplified_main(str(p), "improve") # DiskExecutionEnv(path=p) # del os.environ["GPTE_TEST_MODE"] # Runs gpt-engineer with lite mode and generates a project with only the main prompt. def test_lite_mode_generate_project(self, tmp_path, monkeypatch): p = tmp_path / "projects/example" p.mkdir(parents=True) (p / "prompt").write_text(prompt_text) args = DefaultArgumentsMain( str(p), lite_mode=True, llm_via_clipboard=True, no_execution=True ) args() # Runs gpt-engineer with clarify mode and generates a project after discussing the specification with the AI. def test_clarify_mode_generate_project(self, tmp_path, monkeypatch): p = tmp_path / "projects/example" p.mkdir(parents=True) (p / "prompt").write_text(prompt_text) args = DefaultArgumentsMain( str(p), clarify_mode=True, llm_via_clipboard=True, no_execution=True ) args() # Runs gpt-engineer with self-heal mode and generates a project after discussing the specification with the AI and self-healing the code. def test_self_heal_mode_generate_project(self, tmp_path, monkeypatch): p = tmp_path / "projects/example" p.mkdir(parents=True) (p / "prompt").write_text(prompt_text) args = DefaultArgumentsMain( str(p), self_heal_mode=True, llm_via_clipboard=True, no_execution=True ) args() def test_clarify_lite_improve_mode_generate_project(self, tmp_path, monkeypatch): p = tmp_path / "projects/example" p.mkdir(parents=True) (p / "prompt").write_text(prompt_text) args = DefaultArgumentsMain( str(p), improve_mode=True, lite_mode=True, clarify_mode=True, llm_via_clipboard=True, no_execution=True, ) pytest.raises(typer.Exit, args) # Tests the creation of a log file in improve mode. class TestLoadPrompt: # Load prompt from existing file in input_repo def test_load_prompt_existing_file(self): with tempfile.TemporaryDirectory() as tmp_dir: input_repo = DiskMemory(tmp_dir) prompt_file = "prompt.txt" prompt_content = "This is the prompt" input_repo[prompt_file] = prompt_content improve_mode = False image_directory = "" result = load_prompt(input_repo, improve_mode, prompt_file, image_directory) assert isinstance(result, Prompt) assert result.text == prompt_content assert result.image_urls is None # Prompt file does not exist in input_repo, and improve_mode is False def test_load_prompt_no_file_improve_mode_false(self): with tempfile.TemporaryDirectory() as tmp_dir: input_repo = DiskMemory(tmp_dir) prompt_file = "prompt.txt" improve_mode = False image_directory = "" with patch( "builtins.input", return_value="What application do you want gpt-engineer to generate?", ): result = load_prompt( input_repo, improve_mode, prompt_file, image_directory ) assert isinstance(result, Prompt) assert ( result.text == "What application do you want gpt-engineer to generate?" ) assert result.image_urls is None # Prompt file is a directory def test_load_prompt_directory_file(self): with tempfile.TemporaryDirectory() as tmp_dir: input_repo = DiskMemory(tmp_dir) prompt_file = os.path.join(tmp_dir, "prompt") os.makedirs(os.path.join(tmp_dir, prompt_file)) improve_mode = False image_directory = "" with pytest.raises(ValueError): load_prompt(input_repo, improve_mode, prompt_file, image_directory) # Prompt file is empty def test_load_prompt_empty_file(self): with tempfile.TemporaryDirectory() as tmp_dir: input_repo = DiskMemory(tmp_dir) prompt_file = "prompt.txt" input_repo[prompt_file] = "" improve_mode = False image_directory = "" with patch( "builtins.input", return_value="What application do you want gpt-engineer to generate?", ): result = load_prompt( input_repo, improve_mode, prompt_file, image_directory ) assert isinstance(result, Prompt) assert ( result.text == "What application do you want gpt-engineer to generate?" ) assert result.image_urls is None # image_directory does not exist in input_repo def test_load_prompt_no_image_directory(self): with tempfile.TemporaryDirectory() as tmp_dir: input_repo = DiskMemory(tmp_dir) prompt_file = "prompt.txt" prompt_content = "This is the prompt" input_repo[prompt_file] = prompt_content improve_mode = False image_directory = "tests/test_data" shutil.copytree(image_directory, os.path.join(tmp_dir, image_directory)) result = load_prompt(input_repo, improve_mode, prompt_file, image_directory) assert isinstance(result, Prompt) assert result.text == prompt_content assert "mona_lisa.jpg" in result.image_urls # def test_log_creation_in_improve_mode(self, tmp_path, monkeypatch): # def improve_generator(): # yield "y" # while True: # yield "n" # Subsequent responses # # gen = improve_generator() # monkeypatch.setattr("builtins.input", lambda _: next(gen)) # p = tmp_path / "projects/example" # p.mkdir(parents=True) # (p / "prompt").write_text(prompt_text) # (p / "main.py").write_text("The program will be written in this file") # meta_p = p / META_DATA_REL_PATH # meta_p.mkdir(parents=True) # (meta_p / "file_selection.toml").write_text( # """ # [files] # "main.py" = "selected" # """ # ) # os.environ["GPTE_TEST_MODE"] = "True" # simplified_main(str(p), "improve") # DiskExecutionEnv(path=p) # assert ( # (p / f".gpteng/memory/{DEBUG_LOG_FILE}").read_text().strip() # == """UPLOADED FILES: # ``` # File: main.py # 1 The program will be written in this file # # ``` # PROMPT: # Make a python program that writes 'hello' to a file called 'output.txt' # CONSOLE OUTPUT:""" # ) # del os.environ["GPTE_TEST_MODE"] # # def test_log_creation_in_improve_mode_with_failing_diff( # self, tmp_path, monkeypatch # ): # def improve_generator(): # yield "y" # while True: # yield "n" # Subsequent responses # # def mock_salvage_correct_hunks( # messages: List, files_dict: FilesDict, error_message: List # ) -> FilesDict: # # create a falling diff # messages[ # -1 # ].content = """To create a Python program that writes 'hello' to a file called 'output.txt', we will need to perform the following steps: # # 1. Open the file 'output.txt' in write mode. # 2. Write the string 'hello' to the file. # 3. Close the file to ensure the data is written and the file is not left open. # # Here is the implementation of the program in the `main.py` file: # # ```diff # --- main.py # +++ main.py # @@ -0,0 +1,9 @@ # -create falling diff # ``` # # This concludes a fully working implementation.""" # # Call the original function with modified messages or define your own logic # return salvage_correct_hunks(messages, files_dict, error_message) # # gen = improve_generator() # monkeypatch.setattr("builtins.input", lambda _: next(gen)) # monkeypatch.setattr( # "gpt_engineer.core.default.steps.salvage_correct_hunks", # mock_salvage_correct_hunks, # ) # p = tmp_path / "projects/example" # p.mkdir(parents=True) # (p / "prompt").write_text(prompt_text) # (p / "main.py").write_text("The program will be written in this file") # meta_p = p / META_DATA_REL_PATH # meta_p.mkdir(parents=True) # (meta_p / "file_selection.toml").write_text( # """ # [files] # "main.py" = "selected" # """ # ) # os.environ["GPTE_TEST_MODE"] = "True" # simplified_main(str(p), "improve") # DiskExecutionEnv(path=p) # assert ( # (p / f".gpteng/memory/{DEBUG_LOG_FILE}").read_text().strip() # == """UPLOADED FILES: # ``` # File: main.py # 1 The program will be written in this file # # ``` # PROMPT: # Make a python program that writes 'hello' to a file called 'output.txt' # CONSOLE OUTPUT: # Invalid hunk: @@ -0,0 +1,9 @@ # -create falling diff # # Invalid hunk: @@ -0,0 +1,9 @@ # -create falling diff""" # ) # del os.environ["GPTE_TEST_MODE"] # # def test_log_creation_in_improve_mode_with_unexpected_exceptions( # self, tmp_path, monkeypatch # ): # def improve_generator(): # yield "y" # while True: # yield "n" # Subsequent responses # # def mock_salvage_correct_hunks( # messages: List, files_dict: FilesDict, error_message: List # ) -> FilesDict: # raise Exception("Mock exception in salvage_correct_hunks") # # gen = improve_generator() # monkeypatch.setattr("builtins.input", lambda _: next(gen)) # monkeypatch.setattr( # "gpt_engineer.core.default.steps.salvage_correct_hunks", # mock_salvage_correct_hunks, # ) # p = tmp_path / "projects/example" # p.mkdir(parents=True) # (p / "prompt").write_text(prompt_text) # (p / "main.py").write_text("The program will be written in this file") # meta_p = p / META_DATA_REL_PATH # meta_p.mkdir(parents=True) # (meta_p / "file_selection.toml").write_text( # """ # [files] # "main.py" = "selected" # """ # ) # os.environ["GPTE_TEST_MODE"] = "True" # simplified_main(str(p), "improve") # DiskExecutionEnv(path=p) # assert ( # (p / f".gpteng/memory/{DEBUG_LOG_FILE}").read_text().strip() # == """UPLOADED FILES: # ``` # File: main.py # 1 The program will be written in this file # # ``` # PROMPT: # Make a python program that writes 'hello' to a file called 'output.txt' # CONSOLE OUTPUT: # Error while improving the project: Mock exception in salvage_correct_hunks""" # ) # del os.environ["GPTE_TEST_MODE"] ================================================ FILE: tests/benchmark/test_BenchConfig.py ================================================ # Generated by CodiumAI import pytest from gpt_engineer.benchmark.bench_config import ( AppsConfig, BenchConfig, GptmeConfig, MbppConfig, ) class TestBenchConfig: # Creating a BenchConfig object with default values should return an instance of BenchConfig with all attributes set to their default values. def test_default_values(self): config = BenchConfig() assert isinstance(config.apps, AppsConfig) assert isinstance(config.mbpp, MbppConfig) assert isinstance(config.gptme, GptmeConfig) assert config.apps.active is True assert config.apps.test_start_index == 0 assert config.apps.test_end_index == 1 assert config.apps.train_start_index == 0 assert config.apps.train_end_index == 0 assert config.mbpp.active is True assert config.mbpp.test_len == 1 assert config.mbpp.train_len == 0 assert config.gptme.active is True # Creating a BenchConfig object with specific values should return an instance of BenchConfig with the specified attributes set to the specified values. def test_specific_values(self): config = BenchConfig( apps=AppsConfig( active=False, test_start_index=1, test_end_index=2, train_start_index=3, train_end_index=4, ), mbpp=MbppConfig(active=False, test_len=5, train_len=6), gptme=GptmeConfig(active=False), ) assert isinstance(config.apps, AppsConfig) assert isinstance(config.mbpp, MbppConfig) assert isinstance(config.gptme, GptmeConfig) assert config.apps.active is False assert config.apps.test_start_index == 1 assert config.apps.test_end_index == 2 assert config.apps.train_start_index == 3 assert config.apps.train_end_index == 4 assert config.mbpp.active is False assert config.mbpp.test_len == 5 assert config.mbpp.train_len == 6 assert config.gptme.active is False # Calling the from_dict method with a valid dictionary should return an instance of BenchConfig with attributes set according to the values in the dictionary. def test_from_dict_valid_dict(self): config_dict = { "apps": { "active": False, "test_start_index": 1, "test_end_index": 2, "train_start_index": 3, "train_end_index": 4, }, "mbpp": {"active": False, "test_len": 5, "train_len": 6}, "gptme": {"active": False}, } config = BenchConfig.from_dict(config_dict) assert isinstance(config.apps, AppsConfig) assert isinstance(config.mbpp, MbppConfig) assert isinstance(config.gptme, GptmeConfig) assert config.apps.active is False assert config.apps.test_start_index == 1 assert config.apps.test_end_index == 2 assert config.apps.train_start_index == 3 assert config.apps.train_end_index == 4 assert config.mbpp.active is False assert config.mbpp.test_len == 5 assert config.mbpp.train_len == 6 assert config.gptme.active is False # Calling the from_toml method with an invalid path to a TOML file should raise an appropriate exception. def test_from_toml_invalid_path(self): config_file = "invalid_config.toml" with pytest.raises(Exception): BenchConfig.from_toml(config_file) ================================================ FILE: tests/core/__init__.py ================================================ ================================================ FILE: tests/core/default/__init__.py ================================================ ================================================ FILE: tests/core/default/test_disk_execution_env.py ================================================ import tempfile import unittest from unittest.mock import MagicMock, patch from gpt_engineer.core.default.disk_execution_env import DiskExecutionEnv # from gpt_engineer.core.default.git_version_manager import GitVersionManager from gpt_engineer.core.default.paths import ENTRYPOINT_FILE from gpt_engineer.core.files_dict import FilesDict class TestOnDiskExecutionEnv(unittest.TestCase): def setUp(self): self.temp_dir = tempfile.TemporaryDirectory() self.env = DiskExecutionEnv() def tearDown(self): self.temp_dir.cleanup() def test_successful_execution(self): entrypoint_content = """ python -m venv venv source venv/bin/activate python script.py """ code = { ENTRYPOINT_FILE: entrypoint_content, "script.py": "print('This is a test script')", } with patch("subprocess.Popen") as mock_popen: mock_popen.return_value.wait.return_value = 0 process = self.env.upload(FilesDict(code)).popen(f"bash {ENTRYPOINT_FILE}") self.assertIsNotNone(process) mock_popen.assert_called_once() def test_missing_entrypoint(self): code = {"script.py": "print('This is a test script')"} p = self.env.upload(FilesDict(code)).popen(f"bash {ENTRYPOINT_FILE}") p.communicate() assert p.returncode != 0 def test_keyboard_interrupt_handling(self): entrypoint_content = """ python script.py """ code = { ENTRYPOINT_FILE: entrypoint_content, "script.py": "print('This is a test script')", } with patch("subprocess.Popen") as mock_popen: mock_process = MagicMock() mock_process.poll.side_effect = KeyboardInterrupt mock_popen.return_value = mock_process stdout_full, stderr_full, returncode = self.env.upload(FilesDict(code)).run( f"bash {ENTRYPOINT_FILE}" ) mock_process.kill.assert_called_once() def test_execution_with_output(self): entrypoint_content = """ python script.py """ code = { ENTRYPOINT_FILE: entrypoint_content, "script.py": "import sys; print('Out'); sys.stderr.write('Error')", } with patch("subprocess.Popen") as mock_popen: process = MagicMock() process.wait.return_value = 0 process.communicate.return_value = (b"Out\n", b"Error\n") mock_popen.return_value = process process = self.env.upload(FilesDict(code)).popen(f"bash {ENTRYPOINT_FILE}") stdout, stderr = process.communicate() self.assertEqual(stdout, b"Out\n") self.assertEqual(stderr, b"Error\n") if __name__ == "__main__": unittest.main() ================================================ FILE: tests/core/default/test_disk_file_repository.py ================================================ import pytest from gpt_engineer.core.default.disk_memory import DiskMemory def test_DB_operations(tmp_path): # Test initialization db = DiskMemory(tmp_path) # Test __setitem__ db["test_key"] = "test_value" assert (tmp_path / "test_key").is_file() # Test __getitem__ val = db["test_key"] assert val == "test_value" def test_large_files(tmp_path): db = DiskMemory(tmp_path) large_content = "a" * (10**6) # 1MB of tools # Test write large files db["large_file"] = large_content # Test read large files assert db["large_file"] == large_content def test_concurrent_access(tmp_path): import threading db = DiskMemory(tmp_path) num_threads = 10 num_writes = 1000 def write_to_db(thread_id): for i in range(num_writes): key = f"thread{thread_id}_write{i}" db[key] = str(i) threads = [] for thread_id in range(num_threads): t = threading.Thread(target=write_to_db, args=(thread_id,)) t.start() threads.append(t) for t in threads: t.join() # Verify that all expected tools was written for thread_id in range(num_threads): for i in range(num_writes): key = f"thread{thread_id}_write{i}" assert key in db # using __contains__ now assert db[key] == str(i) def test_error_messages(tmp_path): db = DiskMemory(tmp_path) # Test error on getting non-existent key with pytest.raises(KeyError): db["non_existent"] with pytest.raises(TypeError) as e: db["key"] = ["Invalid", "value"] assert str(e.value) == "val must be str" # Generated by CodiumAI class TestOnDiskRepository: # can set and get a value for a key def test_set_and_get_value(self, tmp_path): db = DiskMemory(tmp_path) db["test_key"] = "test_value" assert (tmp_path / "test_key").is_file() val = db["test_key"] assert val == "test_value" # can check if a key exists in the database def test_key_exists(self, tmp_path): db = DiskMemory(tmp_path) db["test_key"] = "test_value" assert "test_key" in db assert "nonexistent_key" not in db # can fetch a default value if a key does not exist def test_fetch_default_value(self, tmp_path): db = DiskMemory(tmp_path) default_val = "default_value" assert db.get("nonexistent_key", default_val) == default_val # can delete a file or directory in the database def test_delete_file_or_directory(self, tmp_path): db = DiskMemory(tmp_path) db["test_file"] = "test_content" db["test_directory/test_file"] = "test_content" del db["test_file"] del db["test_directory"] assert not (tmp_path / "test_file").exists() assert not (tmp_path / "test_directory").exists() # can iterate over all files in the database def test_iterate_files(self, tmp_path): db = DiskMemory(tmp_path) db["file1.txt"] = "content1" db["file2.txt"] = "content2" db["directory/file3.txt"] = "content3" files = list(db) assert len(files) == 3 assert "file1.txt" in files assert "file2.txt" in files assert "directory/file3.txt" in files # raises a KeyError if a non-existent key is accessed def test_key_error(self, tmp_path): db = DiskMemory(tmp_path) with pytest.raises(KeyError): _ = db["nonexistent_key"] # raises a ValueError if a file name attempts to access parent path def test_value_error(self, tmp_path): db = DiskMemory(tmp_path) with pytest.raises(ValueError): db["../file.txt"] = "content" # raises a TypeError if a non-string value is set for a key def test_type_error(self, tmp_path): db = DiskMemory(tmp_path) with pytest.raises(TypeError): db["test_key"] = 123 # can handle large file contents def test_large_file_contents(self, tmp_path): db = DiskMemory(tmp_path) large_content = "a" * (10**6) # 1MB of tools db["large_file"] = large_content assert db["large_file"] == large_content ================================================ FILE: tests/core/default/test_simple_agent.py ================================================ import tempfile import pytest from langchain.schema import AIMessage from gpt_engineer.core.default.disk_execution_env import DiskExecutionEnv from gpt_engineer.core.default.paths import ENTRYPOINT_FILE from gpt_engineer.core.default.simple_agent import SimpleAgent from gpt_engineer.core.files_dict import FilesDict from gpt_engineer.core.prompt import Prompt from tests.mock_ai import MockAI def test_init(): temp_dir = tempfile.mkdtemp() mock_ai = MockAI( [ AIMessage( "hello_world.py\n```\nwith open('output.txt', 'w') as file:\n file.write('Hello World!')\n```" ), AIMessage("```run.sh\npython3 hello_world.py\n```"), ], ) lean_agent = SimpleAgent.with_default_config(temp_dir, mock_ai) outfile = "output.txt" code = lean_agent.init( Prompt( f"Make a program that prints 'Hello World!' to a file called '{outfile}'" ) ) env = DiskExecutionEnv() env.upload(code).run(f"bash {ENTRYPOINT_FILE}") code = env.download() assert outfile in code assert code[outfile] == "Hello World!" def test_improve(): temp_dir = tempfile.mkdtemp() code = FilesDict( { "main.py": "def write_hello_world_to_file(filename):\n \"\"\"\n Writes 'Hello World!' to the specified file.\n \n :param filename: The name of the file to write to.\n \"\"\"\n with open(filename, 'w') as file:\n file.write('Hello World!')\n\nif __name__ == \"__main__\":\n output_filename = 'output.txt'\n write_hello_world_to_file(output_filename)", "requirements.txt": "# No dependencies required", "run.sh": "python3 main.py\n", } ) mock_ai = MockAI( [ AIMessage( "```diff\n--- main.py\n+++ main.py\n@@ -7,3 +7,3 @@\n with open(filename, 'w') as file:\n- file.write('Hello World!')\n+ file.write('!dlroW olleH')\n```" ) ] ) lean_agent = SimpleAgent.with_default_config(temp_dir, mock_ai) code = lean_agent.improve( code, Prompt( "Change the program so that it prints '!dlroW olleH' instead of 'Hello World!' " ), f"bash {ENTRYPOINT_FILE}", ) env = DiskExecutionEnv() env.upload(code).run(f"bash {ENTRYPOINT_FILE}") code = env.download() outfile = "output.txt" assert outfile in code assert code[outfile] == "!dlroW olleH" if __name__ == "__main__": pytest.main() ================================================ FILE: tests/core/default/test_steps.py ================================================ # Generated by CodiumAI import tempfile from unittest.mock import MagicMock import pytest from langchain.schema import SystemMessage from gpt_engineer.core.ai import AI from gpt_engineer.core.default.disk_memory import DiskMemory from gpt_engineer.core.default.paths import ENTRYPOINT_FILE, PREPROMPTS_PATH from gpt_engineer.core.default.steps import ( curr_fn, gen_code, gen_entrypoint, improve_fn, setup_sys_prompt, setup_sys_prompt_existing_code, ) from gpt_engineer.core.files_dict import FilesDict from gpt_engineer.core.linting import Linting from gpt_engineer.core.preprompts_holder import PrepromptsHolder from gpt_engineer.core.prompt import Prompt factorial_program = """ To implement a function that calculates the factorial of a number in Python, we will create a simple Python module with a single function `factorial`. The factorial of a non-negative integer `n` is the product of all positive integers less than or equal to `n`. It is denoted by `n!`. The factorial of 0 is defined to be 1. Let's start by creating the `factorial.py` file which will contain our `factorial` function. factorial.py ```python def factorial(n: int) -> int: if n < 0: raise ValueError("Factorial is not defined for negative numbers") elif n == 0: return 1 else: result = 1 for i in range(1, n + 1): result *= i return result if __name__ == "__main__": import sys if len(sys.argv) != 2: print("Usage: python factorial.py ") sys.exit(1) try: number = int(sys.argv[1]) print(f"The factorial of {number} is {factorial(number)}") except ValueError as e: print(e) sys.exit(1) ``` Now, let's create a `requirements.txt` file to specify the dependencies for this module. Since we are not using any external libraries, the `requirements.txt` file will be empty, but it's a good practice to include it in Python projects. requirements.txt ``` # No dependencies required ``` This concludes a fully working implementation.``` """ factorial_entrypoint = """ Irrelevant explanations ```sh python3 -m venv venv source venv/bin/activate pip install -r requirements.txt pytest test_factorial.py ``` """ class TestGenCode: # Generates code based on a given prompt using an AI model. def test_generates_code_using_ai_model(self): # Mock AI class class MockAI: def start(self, sys_prompt, user_prompt, step_name): return [SystemMessage(content=factorial_program)] ai = MockAI() prompt = Prompt("Write a function that calculates the factorial of a number.") memory = DiskMemory(tempfile.mkdtemp()) preprompts_holder = PrepromptsHolder(PREPROMPTS_PATH) code = gen_code(ai, prompt, memory, preprompts_holder) assert isinstance(code, FilesDict) assert len(code) == 2 # assert CODE_GEN_LOG_FILE in memory # assert memory[CODE_GEN_LOG_FILE] == factorial_program.strip() # The generated code is saved to disk. def test_generated_code_saved_to_disk(self): # Mock AI class class MockAI: def start(self, sys_prompt, user_prompt, step_name): return [SystemMessage(content=factorial_program)] ai = MockAI() prompt = Prompt("Write a function that calculates the factorial of a number.") memory = DiskMemory(tempfile.mkdtemp()) preprompts_holder = PrepromptsHolder(PREPROMPTS_PATH) code = gen_code(ai, prompt, memory, preprompts_holder) assert isinstance(code, FilesDict) assert len(code) == 2 # assert CODE_GEN_LOG_FILE in memory # assert memory[CODE_GEN_LOG_FILE] == factorial_program.strip() # Raises TypeError if keys are not strings or Path objects. def test_raises_type_error_if_keys_not_strings_or_path_objects(self): # Mock AI class class MockAI: def start(self, sys_prompt, user_prompt, step_name): return [SystemMessage(content=factorial_program)] ai = MockAI() prompt = Prompt("Write a function that calculates the factorial of a number.") memory = DiskMemory(tempfile.mkdtemp()) preprompts_holder = PrepromptsHolder(PREPROMPTS_PATH) with pytest.raises(TypeError): code = gen_code(ai, prompt, memory, preprompts_holder) code[123] = "code" # Raises TypeError if values are not strings. def test_raises_type_error_if_values_not_strings(self): # Mock AI class class MockAI: def start(self, sys_prompt, user_prompt, step_name): return [SystemMessage(content=factorial_program)] ai = MockAI() prompt = Prompt("Write a function that calculates the factorial of a number.") memory = DiskMemory(tempfile.mkdtemp()) preprompts_holder = PrepromptsHolder(PREPROMPTS_PATH) with pytest.raises(TypeError): code = gen_code(ai, prompt, memory, preprompts_holder) code["file.py"] = 123 # Raises KeyError if the file does not exist in the database. def test_raises_key_error_if_file_not_exist_in_database(self): # Mock AI class class MockAI: def start(self, sys_prompt, user_prompt, step_name): return [SystemMessage(content=factorial_program)] ai = MockAI() prompt = Prompt("Write a function that calculates the factorial of a number.") memory = DiskMemory(tempfile.mkdtemp()) preprompts_holder = PrepromptsHolder(PREPROMPTS_PATH) with pytest.raises(KeyError): code = gen_code(ai, prompt, memory, preprompts_holder) code["nonexistent_file.py"] class TestStepUtilities: def test_called_from_function(self): # Arrange def test_function(): return curr_fn() expected_name = "test_function" # Act actual_name = test_function() # Assert assert actual_name == expected_name def test_constructs_system_prompt_with_predefined_instructions_and_philosophies( self, ): preprompts_holder = PrepromptsHolder(PREPROMPTS_PATH) preprompts = preprompts_holder.get_preprompts() sys_prompt = setup_sys_prompt(preprompts) expected_prompt = ( preprompts["roadmap"] + preprompts["generate"].replace("FILE_FORMAT", preprompts["file_format"]) + "\nUseful to know:\n" + preprompts["philosophy"] ) assert sys_prompt == expected_prompt def test_constructs_system_prompt(self): preprompts_holder = PrepromptsHolder(PREPROMPTS_PATH) preprompts = preprompts_holder.get_preprompts() expected_prompt = ( preprompts["roadmap"] + preprompts["improve"].replace( "FILE_FORMAT", preprompts["file_format_diff"] ) + "\nUseful to know:\n" + preprompts["philosophy"] ) actual_prompt = setup_sys_prompt_existing_code(preprompts) assert actual_prompt == expected_prompt class TestGenEntrypoint: class MockAI: def __init__(self, content): self.content = content def start(self, system, user, step_name): return [SystemMessage(content=self.content)] # The function receives valid input and generates a valid entry point script. def test_valid_input_generates_valid_entrypoint(self): # Mock AI class ai_mock = TestGenEntrypoint.MockAI(factorial_entrypoint) code = FilesDict() tempdir = tempfile.mkdtemp() memory = DiskMemory(tempdir) prompt = Prompt("") # Act preprompts_holder = PrepromptsHolder(PREPROMPTS_PATH) entrypoint_code = gen_entrypoint( ai_mock, prompt, code, memory, preprompts_holder ) # Assert assert ENTRYPOINT_FILE in entrypoint_code assert isinstance(entrypoint_code[ENTRYPOINT_FILE], str) assert ( entrypoint_code[ENTRYPOINT_FILE] == """python3 -m venv venv source venv/bin/activate pip install -r requirements.txt pytest test_factorial.py """ ) # assert ENTRYPOINT_LOG_FILE in memory # assert isinstance(memory[ENTRYPOINT_LOG_FILE], str) # assert memory[ENTRYPOINT_LOG_FILE] == factorial_entrypoint.strip() # The function receives an empty codebase and returns an empty entry point script. def test_empty_codebase_returns_empty_entrypoint(self): # Arrange ai_mock = TestGenEntrypoint.MockAI("Irrelevant explanation") code = FilesDict() tempdir = tempfile.mkdtemp() memory = DiskMemory(tempdir) prompt = Prompt("") # Act preprompts_holder = PrepromptsHolder(PREPROMPTS_PATH) entrypoint_code = gen_entrypoint( ai_mock, prompt, code, memory, preprompts_holder ) # Assert assert ENTRYPOINT_FILE in entrypoint_code assert isinstance(entrypoint_code[ENTRYPOINT_FILE], str) assert entrypoint_code[ENTRYPOINT_FILE] == "" # assert ENTRYPOINT_LOG_FILE in memory # assert isinstance(memory[ENTRYPOINT_LOG_FILE], str) # assert memory[ENTRYPOINT_LOG_FILE] == "Irrelevant explanation" class TestImprove: def test_improve_existing_code(self, tmp_path): # Mock the AI class ai_patch = """ Some introductory text. ```diff --- main.py +++ main.py @@ -1,1 +1,1 @@ -print('Hello, World!') +print('Goodbye, World!') ``` """ ai_mock = MagicMock(spec=AI) ai_mock.next.return_value = [SystemMessage(content=ai_patch)] # Create a Code object with existing code code = FilesDict( { "main.py": "print('Hello, World!')", "requirements.txt": "numpy==1.18.1", "README.md": "This is a sample code repository.", } ) # Create a BaseRepository object for memory memory = DiskMemory(tmp_path) # Define the user prompt prompt = Prompt( "Change the program to print 'Goodbye, World!' instead of 'Hello, World!'" ) # Call the improve function preprompts_holder = PrepromptsHolder(PREPROMPTS_PATH) improved_code = improve_fn(ai_mock, prompt, code, memory, preprompts_holder) # Assert that the code was improved correctly expected_code = FilesDict( { "main.py": "print('Goodbye, World!')", "requirements.txt": "numpy==1.18.1", "README.md": "This is a sample code repository.", } ) assert improved_code == expected_code def test_lint_python(self): linting = Linting() content = "print('Hello, world! ')" config = {"line_length": 50} linted_content = linting.lint_python(content, config) assert linted_content is not None, "Linted content should not be None" def test_lint_files(self): linting = Linting() files_dict = FilesDict({"test.py": "print('Hello, world! ')"}) config = {"line_length": 50} linted_files_dict = linting.lint_files(files_dict, config) assert linted_files_dict is not None, "Linted files dict should not be None" assert isinstance( linted_files_dict, FilesDict ), "Output should be an instance of FilesDict" assert ( "test.py" in linted_files_dict ), "test.py should be in the linted files dict" ================================================ FILE: tests/core/improve_function_test_cases/apps_benchmark_6_chat ================================================ To implement this program, we will follow a structured approach. We will create a Python script that takes command-line arguments for the inputs, parses them, and then processes each query to determine the minimum number of blows required to defeat Zmei Gorynich. The program will consist of a main function that handles input parsing and output formatting, and a separate function that calculates the minimum number of blows for each query. We will need to: 1. Parse the command-line arguments to extract the queries. 2. For each query, calculate the minimum number of blows required. 3. Print the result for each query. Let's start by creating the `main.py` file with the necessary imports and the skeleton of our program. ```diff --- /dev/null +++ main.py @@ -0,0 +1,36 @@ +import sys + +def calculate_min_blows(n, x, blows): + """ + Calculate the minimum number of blows to defeat Zmei Gorynich. + :param n: Number of types of blows. + :param x: Initial number of heads. + :param blows: List of tuples (d_i, h_i) for each blow type. + :return: Minimum number of blows or -1 if impossible. + """ + # Implementation will be added here + pass + +def main(): + # Parse command-line arguments + args = sys.argv[1].split() + t = int(args[0]) + queries = [] + idx = 1 + for _ in range(t): + n, x = map(int, args[idx:idx+2]) + idx += 2 + blows = [tuple(map(int, args[idx:idx+2])) for _ in range(n)] + idx += 2*n + queries.append((n, x, blows)) + + # Process each query + for n, x, blows in queries: + result = calculate_min_blows(n, x, blows) + print(result) + +if __name__ == "__main__": + main() ``` Now, let's implement the logic in calculate_min_blows function to determine the minimum number of blows required to defeat Zmei Gorynich. ```diff --- main.py +++ main.py @@ -8,7 +8,25 @@ + # Implementation will be added here + max_damage = max(blows, key=lambda x: x[0]) + max_diff = max(blows, key=lambda x: x[0] - x[1]) + if max_damage[0] >= x: + return 1 + if max_diff[0] <= max_diff[1] and max_damage[0] < x: + return -1 + effective_damage = max_diff[0] - max_diff[1] + remaining_heads = x - max_damage[0] + blows_required = 1 + (remaining_heads + effective_damage - 1) // effective_damage + return blows_required - pass ``` ================================================ FILE: tests/core/improve_function_test_cases/apps_benchmark_6_code ================================================ ================================================ FILE: tests/core/improve_function_test_cases/apps_benchmark_6_v2_chat ================================================ ```diff --- main.py +++ main.py @@ -8,7 +8,25 @@ + # Implementation will be added here + max_damage = max(blows, key=lambda x: x[0]) + max_diff = max(blows, key=lambda x: x[0] - x[1]) + if max_damage[0] >= x: + return 1 + if max_diff[0] <= max_diff[1] and max_damage[0] < x: + return -1 + effective_damage = max_diff[0] - max_diff[1] + remaining_heads = x - max_damage[0] + blows_required = 1 + (remaining_heads + effective_damage - 1) // effective_damage + return blows_required - pass ``` ================================================ FILE: tests/core/improve_function_test_cases/apps_benchmark_6_v2_code ================================================ import sys def calculate_min_blows(n, x, blows): """ Calculate the minimum number of blows to defeat Zmei Gorynich. :param n: Number of types of blows. :param x: Initial number of heads. :param blows: List of tuples (d_i, h_i) for each blow type. :return: Minimum number of blows or -1 if impossible. """ # Implementation will be added here pass def main(): # Parse command-line arguments args = sys.argv[1].split() t = int(args[0]) queries = [] idx = 1 for _ in range(t): n, x = map(int, args[idx:idx+2]) idx += 2 blows = [tuple(map(int, args[idx:idx+2])) for _ in range(n)] idx += 2*n queries.append((n, x, blows)) # Process each query for n, x, blows in queries: result = calculate_min_blows(n, x, blows) print(result) if __name__ == "__main__": main()""" print(code) ================================================ FILE: tests/core/improve_function_test_cases/controller_chat ================================================ Planning: 1. Modify the `handle_input` method within the `Controller` class to change the behavior of the snake when certain keys are pressed. 2. When the "up" key is pressed, we need to queue two actions: first to move "down" and then to move "right" after one step. This will require storing the next move in the `Controller` class and checking for it on subsequent calls to `handle_input`. 3. When the "down" key is pressed, the snake should move "up". 4. When the "left" key is pressed, the snake should move "right". 5. When the "right" key is pressed, the snake should move "left". 6. Remove the long, unnecessary comment block. 7. Since we need to queue actions, we will introduce a new attribute `next_move` to the `Controller` class to store the next move. 8. Update the `__init__` method to initialize `next_move` as `None`. 9. Modify the `handle_input` method to check if there is a `next_move` queued before checking the keyboard input. If there is a `next_move`, execute it and clear the `next_move`. 10. Update the `handle_input` method to set the `next_move` to "right" when the "up" key is pressed, after moving "down". 11. Update the `handle_input` method to handle the reversed directions for "down", "left", and "right" keys. Generate patches: ```diff --- controller.py +++ controller.py @@ -4,6 +4,7 @@ class Controller: def __init__(self, game, view): self.game = game self.view = view + self.next_move = None def handle_input(self): + if self.next_move: + self.game.move(self.next_move) + self.next_move = None + else: - if keyboard.is_pressed("up"): - self.game.move("up") + if keyboard.is_pressed("up"): + self.game.move("down") + self.next_move = "right" - elif keyboard.is_pressed("down"): + elif keyboard.is_pressed("down"): - """ - long - goring comment - - - - - - - - - """ - self.game.move("down") + self.game.move("up") - elif keyboard.is_pressed("left"): - self.game.move("left") + elif keyboard.is_pressed("left"): + self.game.move("right") - elif keyboard.is_pressed("right"): - self.game.move("right") + elif keyboard.is_pressed("right"): + self.game.move("left") ``` ================================================ FILE: tests/core/improve_function_test_cases/controller_code ================================================ import keyboard class Controller: def __init__(self, game, view): self.game = game self.view = view def handle_input(self): if keyboard.is_pressed("up"): self.game.move("up") elif keyboard.is_pressed("down"): """ long goring comment """ self.game.move("down") elif keyboard.is_pressed("left"): self.game.move("left") elif keyboard.is_pressed("right"): self.game.move("right") ================================================ FILE: tests/core/improve_function_test_cases/corrected_diff_from_missing_lines ================================================ --- example.txt +++ example.txt @@ -12,7 +12,8 @@ sample text 1 sample text 2 + added extra line here # #comment # # - original text A + updated original text A with changes @@ -39,4 +40,5 @@ checking status: - perform operation X + perform operation X only if specific condition holds + new operation related to condition evaluating next step: - execute step Y + revised execution of step Y ================================================ FILE: tests/core/improve_function_test_cases/create_two_new_files_chat ================================================ To implement the requested functionality, we'll create a Python program that processes the input, evaluates the service history of a car, and outputs the appropriate message based on the criteria provided. We'll structure the program into several parts: 1. **Parsing Input**: A function to parse the input string into a structured format. 2. **Service History Evaluation**: A class to evaluate the service history entries and determine the status of the odometer and service frequency. 3. **Main Logic**: The main logic that ties everything together and outputs the final result. Let's start by creating the necessary files and writing the initial code. ### File: requirements.txt This file will list the dependencies required for the project. Since the project does not require external libraries, this file will be empty but included for completeness. ```diff ``` ### File: service_history_evaluator.py This file will contain the class responsible for evaluating the service history. ```diff --- /dev/null +++ service_history_evaluator.py @@ -0,0 +1,47 @@ +from datetime import datetime, timedelta + +class ServiceHistoryEvaluator: + """ + Evaluates the service history of a car to determine if the odometer has been tampered with + or if the service frequency is insufficient. + """ + def __init__(self, entries): + self.entries = entries + + def evaluate(self): + # Placeholder for the evaluation logic + pass + + def _parse_date(self, year, month): + """ + Parses the year and month into a datetime object. + """ + return datetime(year, month, 1) + + def _calculate_distance(self, start, end): + """ + Calculates the minimum and maximum possible distance traveled between two services. + """ + months_diff = (end.year - start.year) * 12 + end.month - start.month + min_distance = 2000 * months_diff + max_distance = 20000 * months_diff + return min_distance, max_distance + + def _check_odometer_rollover(self, prev_reading, current_reading, max_distance): + """ + Checks if the odometer could have rolled over between two readings. + """ + if prev_reading > current_reading: + return current_reading + (99999 - prev_reading) <= max_distance + else: + return current_reading - prev_reading <= max_distance + + def _check_service_frequency(self): + """ + Checks if the service frequency is within the legal limits. + """ + # Placeholder for the service frequency check logic + pass ``` ### File: main.py This file will contain the main logic and the entry point of the program. ```diff --- /dev/null +++ main.py @@ -0,0 +1,29 @@ +import sys +from service_history_evaluator import ServiceHistoryEvaluator + +def parse_input(input_str): + """ + Parses the input string into a structured format. + """ + lines = input_str.split('\n') + num_entries = int(lines[0]) + entries = [tuple(map(int, line.split())) for line in lines[1:num_entries+1]] + return entries + +def main(input_str): + entries = parse_input(input_str) + evaluator = ServiceHistoryEvaluator(entries) + result = evaluator.evaluate() + print(result) + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("Usage: python main.py 'input1 input2 etc'") + sys.exit(1) + input_str = sys.argv[1].replace("'", "") + main(input_str) ``` ================================================ FILE: tests/core/improve_function_test_cases/create_two_new_files_code ================================================ ================================================ FILE: tests/core/improve_function_test_cases/simple_calculator_chat ================================================ I apologize for the oversight. Let's correct the `calculator.py` file with the proper git diff format, ensuring that the context lines match the original code exactly. ```diff --- calculator.py +++ calculator.py @@ -1,24 +1,24 @@ class Calculator: - def add(self, a, b): - return a - b # Logical + def add(self, a, b): # Adds two numbers + return a + b - def subtract(self, a, b) + def subtract(self, a, b): # Subtracts second number from first + return a - b - def multiply(self, a, b): - return lambda a, b: sum(a for _ in range(abs(b))) * (1 if b >= 0 else -1) #unncessary + def multiply(self, a, b): # Multiplies two numbers + return a * b def divide(self, a, b): if b == 0: raise ValueError("Cannot divide by zero.") return a / b - def modulo(self, a, b): - if b = 0: # Syntax - return None # Logical + def modulo(self, a, b): # Finds the remainder of division of two numbers + if b == 0: + raise ValueError("Cannot modulo by zero.") return a % b def power(self, a, b): # Raises a number to the power of another result = 1 - for i in range(b): # Logical + for i in range(abs(b)): result *= a - return result + return result if b >= 0 else 1 / result ``` Now, let's create the `main.py` file with the correct git diff format: ```diff --- /dev/null +++ main.py @@ -0,0 +1,30 @@ +from calculator import Calculator + +# Function to demonstrate the usage of the Calculator class +def main(): + calc = Calculator() + while True: + try: + a = float(input("Enter the first number: ")) + b = float(input("Enter the second number: ")) + operation = input("Enter an operation (add, subtract, multiply, divide, modulo, power): ").lower() + if operation == 'add': + print("Result:", calc.add(a, b)) + elif operation == 'subtract': + print("Result:", calc.subtract(a, b)) + elif operation == 'multiply': + print("Result:", calc.multiply(a, b)) + elif operation == 'divide': + print("Result:", calc.divide(a, b)) + elif operation == 'modulo': + print("Result:", calc.modulo(a, b)) + elif operation == 'power': + print("Result:", calc.power(a, b)) + else: + print("Invalid operation.") + + if input("Do you want to perform another calculation? (yes/no): ").lower() != 'yes': + break + except Exception as e: + print("Error:", e) + +if __name__ == "__main__": + main() ``` These changes should now correctly apply to the provided code and create a simple calculator program with a command-line interface. ================================================ FILE: tests/core/improve_function_test_cases/simple_calculator_code ================================================ class Calculator: def add(self, a, b): return a - b # Logical def subtract(self, a, b) return a - b # Syntax def multiply(self, a, b): return lambda a, b: sum(a for _ in range(abs(b))) * (1 if b >= 0 else -1) #unncessary def divide(self, a, b): if b == 0: raise ValueError("Cannot divide by zero.") return a / b def modulo(self, a, b): if b = 0: # Syntax return None # Logical return a % b def power(self, a, b): result = 1 for i in range(b): # Logical result *= a return result ================================================ FILE: tests/core/improve_function_test_cases/task_master_chat ================================================ Apologies for the confusion. Let's correct the issues in the code with the proper git diff format: ```diff --- taskmaster.py +++ taskmaster.py @@ -1,4 +1,4 @@ -improt datetime +import datetime class Task: def __init__(self, title, due_date, priority=1): @@ -4,7 +4,7 @@ self.title = tile self.due_date = due_date self.completed = Fasle - self.priority = priority + self.priority = priority # Priority levels: 1 (low) to 5 (high), default is 1. def mark_as_complete(self): - self.completed = Ture + self.completed = True @@ -13,7 +13,7 @@ def update_title(self, new_title): # Correct the typo in the assignment of the new title. # The correct variable name is 'new_title', not 'new_tile'. - self.title = new_tile + self.title = new_title def update_due_date(self, new_date): self.due_date = new_date @@ -22,7 +22,7 @@ def add_task(task_list, task): # Correct the typo in the append method call. # The correct method name is 'append', not 'appned'. - task_list.appned(task) + task_list.append(task) def remove_task(task_list, task_title): for task in task_list: @@ -26,7 +26,7 @@ # Correct the typo in the title attribute check. # The correct attribute name is 'title', not 'titel'. if task.titel == task_title: - task_list.remove(task) + task.title == task_title break def update_task_title(task_list, old_title, new_title): @@ -49,7 +49,7 @@ def print_tasks(task_list): for task in task_list: # Correct the typo in the title attribute when formatting the string. # The correct attribute name is 'title', not 'titel'. - print(f"Task: {task.titel}, Due: {task.due_date}, Completed: {task.completed}, Priority: {task.priority}") + print(f"Task: {task.title}, Due: {task.due_date}, Completed: {task.completed}, Priority: {task.priority}") def load_tasks_from_file(file_path): tasks = [] @@ -55,8 +55,8 @@ with open(file_path, 'r') as file: # Correct the typo in the readlines method call. # The correct method name is 'readlines', not 'redlines'. - lines = file.redlines() + lines = file.readlines() for line in lines: # Correct the typo in the split method call. # The correct method name is 'split', not 'splt'. - parts = line.splt(',') + parts = line.split(',') task = Task(parts[0], parts[1], int(parts[3])) if parts[2].strip() == 'True': task.mark_as_complete() @@ -72,7 +72,7 @@ def find_overdue_tasks(task_list): overdue_tasks = [] current_date = datetime.datetime.now().date() for task in task_list: - task_date = datetime.datetime.strptime(task.due_date, '%Y-%m-%d').date() + task_date = datetime.datetime.strptime(task.due_date.strip(), '%Y-%m-%d').date() if task_date < current_date: # Correct the typo in the append method call. # The correct method name is 'append', not 'appnd'. - overdue_tasks.appnd(task) + overdue_tasks.append(task) return overdue_tasks def search_tasks(task_list, search_term): @@ -83,7 +83,7 @@ for task in task_list: if search_term.lower() in task.title.lower(): # Correct the typo in the append method call. # The correct method name is 'append', not 'appnd'. - found_tasks.appnd(task) + found_tasks.append(task) return found_tasks task_list = [] ``` ================================================ FILE: tests/core/improve_function_test_cases/task_master_code ================================================ improt datetime class Task: def __init__(self, title, due_date, priority=1): self.title = tile self.due_date = due_date self.completed = Fasle self.priority = priority def mark_as_complete(self): self.completed = Ture def update_title(self, new_title): self.title = new_tile def update_due_date(self, new_date): self.due_date = new_date def set_priority(self, priority): self.priority = priority def add_task(task_list, task): task_list.appned(task) def remove_task(task_list, task_title): for task in task_list: if task.titel == task_title: task_list.remove(task) break def update_task_title(task_list, old_title, new_title): for task in task_list: if task.title == old_title: task.update_title(new_title) break def update_task_due_date(task_list, title, new_date): for task in task_list: if task.title == title: task.update_due_date(new_date) break def set_task_priority(task_list, title, priority): for task in task_list: if task.title == title: task.set_priority(priority) break def print_tasks(task_list): for task in task_list: print(f"Task: {task.titel}, Due: {task.due_date}, Completed: {task.completed}, Priority: {task.priority}") def load_tasks_from_file(file_path): tasks = [] with open(file_path, 'r') as file: lines = file.redlines() for line in lines: parts = line.splt(',') task = Task(parts[0], parts[1], int(parts[3])) if parts[2].strip() == 'True': task.mark_as_complete() tasks.append(task) return tasks def save_tasks_to_file(task_list, file_path): with open(file_path, 'w') as file: for task in task_list: line = f"{task.title},{task.due_date},{task.completed},{task.priority}\n" file.write(line) def find_overdue_tasks(task_list): overdue_tasks = [] current_date = datetime.datetime.now().date() for task in task_list: task_date = datetime.datetime.strptime(task.due_date, '%Y-%m-%d').date() if task_date < current_date: overdue_tasks.appnd(task) return overdue_tasks def search_tasks(task_list, search_term): found_tasks = [] for task in task_list: if search_term.lower() in task.title.lower(): found_tasks.appnd(task) return found_tasks task_list = [] add_task(task_list, Task("Finish project", "2024-01-01", 3)) add_task(task_list, Task("Buy groceries", "2024-01-05", 2)) add_task(task_list, Task("Call John", "2024-01-03", 1)) print_tasks(task_list) overdue = find_overdue_tasks(task_list) print("Overdue tasks:") for task in overdue: print(f"Task: {task.title}, Due: {task.due_date}, Priority: {task.priority}") save_tasks_to_file(task_list, "tasks.txt") loaded_tasks = load_tasks_from_file("tasks.txt") print("Loaded tasks:") print_tasks(loaded_tasks) remove_task(task_list, "Buy groceries") print("Tasks after removal:") print_tasks(task_list) save_tasks_to_file(task_list, "tasks_updated.txt") search_results = search_tasks(task_list, "project") print("Search results for 'project':") for task in search_results: print(f"Task: {task.title}, Due: {task.due_date}, Completed: {task.completed}, Priority: {task.priority}") ================================================ FILE: tests/core/improve_function_test_cases/temperature_converter_chat ================================================ Apologies for the confusion. Let's provide the corrected git diff patches for the `temperatureconverter.py` file. ```diff --- temperatureconverter.py +++ temperatureconverter.py @@ -6,2 +6,3 @@ - def _fahrenheit_to_celsius(self, fahrenheit) + def _fahrenheit_to_celsius(self, fahrenheit): + """Convert Fahrenheit to Celsius.""" return (fahrenheit - 32) * 5 // 9 @@ -15,2 +16,3 @@ - def _fahrenheit_to_kelvin(self, fahrenheit) + def _fahrenheit_to_kelvin(self, fahrenheit): + """Convert Fahrenheit to Kelvin.""" return self._celsius_to_kelvin(self._fahrenheit_to_celsius(fahrenheit)) @@ -18,2 +20,3 @@ - def _kelvin_to_fahrenheit(self, kelvin): + def _kelvin_to_fahrenheit(self, kelvin): + """Convert Kelvin to Fahrenheit.""" return self._celsius_to_fahrenheit(self._kelvin_to_celsius(kelvin)) @@ -21,3 +24,4 @@ def convert_temperature(self, temperature, from_scale, to_scale): + """Convert temperature from one scale to another.""" conversion_methods = { ('Celsius', 'Fahrenheit'): self._celsius_to_fahrenheit, @@ -30,3 +34,4 @@ - if (from_scale, to_scale) in conversion_methods - return conversion_methods[(from_scale, to_scale(temperature) + if (from_scale, to_scale) in conversion_methods: + return conversion_methods[(from_scale, to_scale)](temperature) else: @@ -35,3 +40,4 @@ def update_base_temperature(self, new_temperature, scale): + """Update the base temperature after validating the new temperature.""" if self.is_temperature_valid(new_temperature, scale): - self.base_temp = convert_temperature(new_temperature, scale, self.scale) + self.base_temp = self.convert_temperature(new_temperature, scale, self.scale) else: @@ -41,3 +47,4 @@ def set_scale(self, new_scale): + """Set a new scale and update the base temperature accordingly.""" if new_scale not in ["Celsius", "Fahrenheit", "Kelvin"]: @@ -47,3 +54,4 @@ def __str__(self): + """Return a string representation of the base temperature and scale.""" - return "Base Temperature: " + self.base_temp + " " + self.scale + return f"Base Temperature: {self.base_temp} {self.scale}" @@ -50,3 +58,4 @@ def __repr__(self): + """Return a string representation of the TemperatureConverter instance for debugging.""" - return "TemperatureConverter(base_temperature=" + self.base_temperature + ", scale='" + self.scale + "')" + return f"TemperatureConverter(base_temperature={self.base_temp}, scale='{self.scale}')" + + # Add missing conversion methods + def _celsius_to_fahrenheit(self, celsius): + """Convert Celsius to Fahrenheit.""" + return (celsius * 9 / 5) + 32 + + def _kelvin_to_fahrenheit(self, kelvin): + """Convert Kelvin to Fahrenheit.""" + return (kelvin - 273) * 9 / 5 + 32 + + # Add method to validate temperatures + def is_temperature_valid(self, temperature, scale): + """Validate the correctness of the given temperature within the specified scale.""" + if scale == "Celsius": + return -273 <= temperature + elif scale == "Fahrenheit": + return -459 <= temperature + elif scale == "Kelvin": + return 0 <= temperature + return False + + # Add method to reset the base temperature + def reset_base_temperature(self): + """Reset the base temperature to the default value.""" + self.base_temp = 0 + self.scale = "Celsius" ``` This diff corrects the syntax errors, adds missing methods, and includes the necessary changes to ensure the `TemperatureConverter` class works as intended. The `__str__` and `__repr__` methods have been fixed to properly format the temperature as a string, and the `set_scale` and `update_base_temperature` methods have been corrected to use the class's methods properly. Additionally, the `is_temperature_valid` method has been added to validate temperatures, and a method to reset the base temperature has been included. ================================================ FILE: tests/core/improve_function_test_cases/temperature_converter_code ================================================ class TemperatureConverter def __init__(self, base_temperature=0, scale="Celsius"): self.base_temp = base_temperature self.scale = scale if scale in ["Celsius", "Fahrenheit", "Kelvin"] else "Invalid" def _fahrenheit_to_celsius(self, fahrenheit) return (fahrenheit - 32) * 5 // 9 def celsius_to_kelvin(self, celsius): return celsius + 273 def kelvin_to_celsius(self, kelvin): return kelvin - 273 def _fahrenheit_to_kelvin(self, fahrenheit) return self._celsius_to_kelvin(_fahrenheit_to_celsius(fahrenheit)) def _kelvin_to_fahrenheit(self, kelvin): return self._celsius_to_fahrenheit(_kelvin_to_celsius(kelvin) def convert_temperature(self, temperature, from_scale, to_scale): conversion_methods = { ('Celsius', 'Fahrenheit'): self._celsius_to_fahrenheit, ('Celsius', 'Kelvin'): self.celsius_to_kelvin, ('Fahrenheit', 'Celsius'): self._fahrenheit_to_celsius, ('Fahrenheit', 'Kelvin'): self._fahrenheit_to_kelvin, ('Kelvin', 'Celsius'): self.kelvin_to_celsius, ('Kelvin', 'Fahrenheit'): self._kelvin_to_fahrenheit, } if (from_scale, to_scale) in conversion_methods return conversion_methods[(from_scale, to_scale(temperature) else raise ValueError("Invalid scale conversion") def update_base_temperature(self, new_temperature, scale): if self.is_temperature_valid(new_temperature, scale): self.base_temp = convert_temperature(new_temperature, scale, self.scale) else: raise ValueError("Invalid temperature value") def set_scale(self, new_scale): if new_scale not in ["Celsius", "Fahrenheit", "Kelvin"]: print("Invalid scale") self.base_temp = self.convert_temperature(self.base_temperature, self.scale, new_scale) self.scale = new_scale def __str__(self): return "Base Temperature: " + self.base_temp + " " + self.scale def __repr__(self): return "TemperatureConverter(base_temperature=" + self.base_temperature + ", scale='" + self.scale + "')" ================================================ FILE: tests/core/improve_function_test_cases/theo_case_chat ================================================ To add an entrypoint for running the API through the command line, we will create a new Python script that can be executed directly. This script will set up and run the FastAPI application using Uvicorn, which is an ASGI server. This approach allows you to run the server from the command line without directly using the `uvicorn` command. We will create a new file named `run.py` in the root directory. This file will import the FastAPI application from `main.py` and will use Uvicorn to run it. Here's the implementation: ```diff --- /dev/null +++ run.py @@ -0,0 +1,10 @@ +import uvicorn +from main import app + +# This script can be used to run the FastAPI application from the command line. +if __name__ == "__main__": + uvicorn.run(app, host="0.0.0.0", port=8000) ``` This script checks if it is being run as the main module and then starts the Uvicorn server with the FastAPI app. The server listens on all interfaces (`0.0.0.0`) and port `8000`. Additionally, we need to update the Dockerfile to ensure that the new script is correctly utilized when the Docker container is run. We will change the CMD directive to use `run.py` instead of directly calling `uvicorn`. ```diff --- dockerfile +++ dockerfile @@ -19,3 +19,3 @@ -# Run app.py when the container launches -CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"] +# Run run.py when the container launches +CMD ["python", "run.py"] ``` This change in the Dockerfile ensures that when the Docker container is started, it uses the new `run.py` script to launch the application. This script sets up the Uvicorn server with the specified host and port settings. With these changes, you can now run the API both directly from the command line by executing `python run.py` and through Docker using the updated Dockerfile configuration. This setup provides flexibility for different deployment scenarios.Invalid hunk: @@ -19,3 +19,3 @@ -# Run app.py when the container launches -CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"] +# Run run.py when the container launches +CMD ["python", "run.py"] To add an entrypoint for running the API through the command line, we will create a new Python script that can be executed directly. This script will set up and run the FastAPI application using Uvicorn, which is an ASGI server. This approach allows you to run the server from the command line without directly using the `uvicorn` command. We will create a new file named `run.py` in the root directory. This file will import the FastAPI application from `main.py` and will use Uvicorn to run it. Here's the implementation: ```diff --- /dev/null +++ run.py @@ -0,0 +1,10 @@ +import uvicorn +from main import app + +# This script can be used to run the FastAPI application from the command line. +if __name__ == "__main__": + uvicorn.run(app, host="0.0.0.0", port=8000) ``` This script checks if it is being run as the main module and then starts the Uvicorn server with the FastAPI app. The server listens on all interfaces (`0.0.0.0`) and port `8000`. Additionally, we need to update the Dockerfile to ensure that the new script is correctly utilized when the Docker container is run. We will change the CMD directive to use `run.py` instead of directly calling `uvicorn`. ```diff --- dockerfile +++ dockerfile @@ -19,3 +19,3 @@ -# Run app.py when the container launches -CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"] +# Run run.py when the container launches +CMD ["python", "run.py"] ``` This change in the Dockerfile ensures that when the Docker container is started, it uses the new `run.py` script to launch the application. This script sets up the Uvicorn server with the specified host and port settings. With these changes, you can now run the API both directly from the command line by executing `python run.py` and through Docker using the updated Dockerfile configuration. This setup provides flexibility for different deployment scenarios.Invalid hunk: @@ -19,3 +19,3 @@ -# Run app.py when the container launches -CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"] +# Run run.py when the container launches +CMD ["python", "run.py"] ================================================ FILE: tests/core/improve_function_test_cases/theo_case_code ================================================ # Use an official Python runtime as a parent image FROM python:3.9-slim # Set the working directory in the container WORKDIR /usr/src/app # Copy the current directory contents into the container at /usr/src/app COPY . /usr/src/app # Install any needed packages specified in requirements.txt RUN pip install --no-cache-dir -r requirements.txt # Make port 80 available to the world outside this container EXPOSE 80 # Define environment variable ENV NAME World # Run app.py when the container launches CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"] ================================================ FILE: tests/core/improve_function_test_cases/vgvishesh_example_2_chat ================================================ To implement a toggle button for switching between dark and light modes, we need to follow these steps: 1. Update the `App.tsx` file to include state management for the theme mode. We will use React's `useState` hook to manage the theme state and `useEffect` hook to apply the theme to the document body class. 2. Add a button in the `App.tsx` file that will toggle the theme state when clicked. This button should be styled and positioned in the top right corner of the screen. 3. Update the `styles.css` file to include styles for the dark mode. We will define a new class, say `.dark-mode`, that will contain the dark mode styles. This class will be applied to the body when the dark mode is active. 4. Update the `styles.css` file to style the toggle button. Here are the diffs for the changes: ```diff --- src/App.tsx +++ src/App.tsx @@ -1,5 +1,9 @@ import React from 'react'; +import { useState, useEffect } from 'react'; import QRCode from 'qrcode.react'; import { profiles } from './components/SocialLinks'; import { SocialLinks } from './components/SocialLinks'; +import './styles.css'; +const THEME_LIGHT = 'light'; +const THEME_DARK = 'dark'; @@ -6,7 +10,23 @@ const App: React.FC = () => { + const [theme, setTheme] = useState(THEME_LIGHT); + + useEffect(() => { + document.body.className = theme; + }, [theme]); + + const toggleTheme = () => { + setTheme(theme === THEME_LIGHT ? THEME_DARK : THEME_LIGHT); + }; + return ( +

My Social Profiles QR Code

@@ -18,4 +38,4 @@ }; export default App; ``` ================================================ FILE: tests/core/improve_function_test_cases/vgvishesh_example_2_code ================================================ import React from 'react'; import QRCode from 'qrcode.react'; import { profiles } from './components/SocialLinks'; import { SocialLinks } from './components/SocialLinks'; const App: React.FC = () => { return (

My Social Profiles QR Code

); }; export default App; ================================================ FILE: tests/core/improve_function_test_cases/vgvishesh_example_chat ================================================ Planning: ........ ```diff --- src/components/SocialLinks.tsx +++ src/components/SocialLinks.tsx @@ -1,10 +1,11 @@ import React from 'react'; +export const profiles = { - const profiles = { linkedIn: 'https://www.linkedin.com/', github: 'https://github.com/', whatsapp: 'https://', twitter: 'https://twitter.com/', - }; +}; export const SocialLinks: React.FC = () => { ``` ================================================ FILE: tests/core/improve_function_test_cases/vgvishesh_example_code ================================================ import React from 'react'; export const SocialLinks: React.FC = () => { const profiles = { linkedIn: 'https://www.linkedin.com/', github: 'https://github.com/', whatsapp: 'https://', twitter: 'https://twitter.com/', }; return (
================================================ FILE: tests/core/improve_function_test_cases/wheaties_example_chat ================================================ Planning: 1. Refactor the DNS logic to ensure that DNS records are created for every server hostname and sent to every domain controller. This involves creating a function that encapsulates the DNS record creation logic and iterates over all domain controllers to apply the changes. 2. Remove redundant logic and checks that are scattered throughout the DNS section of the script. Consolidate the logic into a single, reusable function. 3. Replace the multiple if-else statements that determine the `$Zone` variable with a more efficient method, possibly using a hashtable or a switch statement to map server domains to their respective zones. 4. Ensure that the script follows PowerShell best practices, such as using approved verbs for function names, providing comment-based help, and using try-catch blocks for error handling. 5. Add comprehensive comments to the new function and throughout the DNS logic to explain the purpose and functionality of the code. 6. Test the refactored DNS logic to ensure it works correctly in various scenarios and that DNS records are created and propagated as expected. Now, let's generate the diffs for the changes: ```diff --- VMClonetest.ps1 +++ VMClonetest.ps1 @@ -443,3 +443,3 @@ # Minimum - # Sleep 150 -- optional: true was added to /etc/netplan/00-* to resolve this + # Sleep 150 -- optional: true was added to /etc/netplan/00-* to resolve this, but now handled dynamically @@ -455,3 +455,3 @@ ###IF DC's Change - You Will Need To WinRM Accept Them### - if($server_domain -like "ls") + # The logic for determining the DNS zone has been refactored into a function for clarity and maintainability @@ -487,3 +487,3 @@ - Write-Host $serverIpReverse + # The serverIpReverse is now handled within the Create-DnsRecords function for each domain controller @@ -491,3 +491,3 @@ $sb = { - param($Zone,$server_name_lower,$server_ip,$serverIpReverse,$server_domain) + param($Zone,$server_name_lower,$server_ip,$server_domain) @@ -494,3 +494,3 @@ $test = Get-DNSServerResourceRecord -RRType A -ZoneName $Zone -Name $server_name_lower - if($test -ne $null) + # The check for existing DNS records has been moved to the Create-DnsRecords function @@ -500,3 +500,3 @@ elseif($null -eq $test) - { + # The logic for adding DNS records has been moved to the Create-DnsRecords function @@ -512,3 +512,3 @@ # Improved the selection of the domain controller and removed unnecessary comments - # Modify for all DCs + # The selection of domain controllers has been refactored into the Create-DnsRecords function @@ -536,3 +536,3 @@ if (($server_domain -like "CTN" -or $server_domain -like "contoso")) - { + # The logic for creating DNS records on domain controllers has been refactored into the Create-DnsRecords function @@ -547,3 +547,3 @@ Remove-PSSession $session - } + # The session removal is now handled within the Create-DnsRecords function @@ -548,3 +548,3 @@ elseif($server_domain -like "RR" -or $server_domain -like "railrug") - { + # The logic for creating DNS records on domain controllers has been refactored into the Create-DnsRecords function @@ -558,3 +558,3 @@ Remove-PSSession $session - } + # The session removal is now handled within the Create-DnsRecords function @@ -560,3 +560,3 @@ elseif($server_domain -like "DMZ" -or $server_domain -like "lsdmz") - { + # The logic for creating DNS records on domain controllers has been refactored into the Create-DnsRecords function @@ -570,3 +570,3 @@ Remove-PSSession $session - } + # The session removal is now handled within the Create-DnsRecords function @@ -572,3 +572,3 @@ elseif ($server_domain -like "BN" -or $server_domain -like "contoso") - { + # The logic for creating DNS records on domain controllers has been refactored into the Create-DnsRecords function @@ -582,3 +582,3 @@ Remove-PSSession $session - } + # The session removal is now handled within the Create-DnsRecords function @@ -584,3 +584,3 @@ elseif ($server_domain -like "CSX" -or $server_domain -like "contoso") - { + # The logic for creating DNS records on domain controllers has been refactored into the Create-DnsRecords function @@ -594,3 +594,3 @@ Remove-PSSession $session - } + # The session removal is now handled within the Create-DnsRecords function @@ -596,3 +596,3 @@ elseif ($server_domain -like "UP" -or $server_domain -like "lsup") - { + # The logic for creating DNS records on domain controllers has been refactored into the Create-DnsRecords function @@ -607,3 +607,3 @@ Remove-PSSession $session - } + # The session removal is now handled within the Create-DnsRecords function @@ -608,3 +608,3 @@ else - { + # The logic for handling DNS record creation failures has been refactored into the Create-DnsRecords function @@ -611,3 +611,3 @@ Write-Host "No DNS entry was created for " $server_name_lower -BackgroundColor Red - } + # The error message is now handled within the Create-DnsRecords function @@ -613,3 +613,3 @@ ###END CHANGES### - } + # The end of the DNS logic section has been refactored for clarity and maintainability @@ -616,3 +616,3 @@ Write-Host "Created $vm_name with $server_ip for $server_car" - } + # The success message is now part of the Create-DnsRecords function @@ -618,3 +618,3 @@ # Disconnect from vCenter only if there is an active session - $currentSession = Get-PSSession -Name $vcenter -ErrorAction SilentlyContinue + # The logic for disconnecting from vCenter has been refactored for clarity and maintainability @@ -622,3 +622,3 @@ Disconnect-VIServer $vcenter -Confirm:$false - } else { + # The else block has been refactored for clarity and maintainability @@ -625,3 +625,3 @@ Write-Verbose "No active vCenter session to disconnect from: $vcenter" -Verbose:$VerboseMode - } + # The verbose message is now part of the refactored vCenter disconnection logic @@ -630,3 +630,3 @@ # Improved cleanup of variables with better error handling and corrected indentation -# Correct the final cleanup section + # The final cleanup section has been refactored for clarity and maintainability @@ -634,3 +634,3 @@ Get-Variable -Exclude "PWD", "*Preference", "server_lists" | Remove-Variable -ErrorAction SilentlyContinue -} catch { +} # The catch block has been refactored for clarity and maintainability @@ -636,3 +636,3 @@ Write-Host "Error clearing variables: $($_.Exception.Message)" -ForegroundColor Red -} +} # The error message is now part of the refactored variable cleanup logic @@ -640,3 +640,3 @@ Write-Host "Total execution time: $($stopwatch.Elapsed.ToString())" -} +} # The execution time message is now part of the refactored script completion logic ``` These changes yield a fully functional program according to the instructions.Number of matches in test string 1: 1 ================================================ FILE: tests/core/improve_function_test_cases/wheaties_example_code ================================================ using namespace System.Collections.Generic param( [string]$CsvPath = "C:\Powershell\Files\tests2.csv", [switch]$VerboseMode ) # Start the stopwatch to measure the duration of the script execution $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() #----------------------------------------------------------------[DCs]--------------------------------------------------------------- $myList = [List[string]]@('lsdc3.contoso.com','rrdc3.contoso.com','contdc1.contoso.com','osodc1.contoso.com','updc1.contoso.com') #-----------------------------------------------------------[Declarations]----------------------------------------------------------- <# .DESCRIPTION The script reads a CSV file containing VM specifications, sorts the entries by car, and then clones VMs based on the provided templates. It handles different accounts and domains, sets up credentials, and configures network settings for each VM. .PARAMETER CsvPath The path to the CSV file containing the VM specifications. .EXAMPLE PS> .\New-VMClone2.ps1 -CsvPath "C:\Powershell\Files\server_creation_rev5.csv" .NOTES Author: mike wheat Date: 01/23/2024 #> # Import VM List from the specified CSV file try { $vmList = Import-Csv -Path $CsvPath -ErrorAction Stop Write-Verbose "CSV file imported successfully." -Verbose:$VerboseMode } catch { Write-Host "Error importing CSV: $($_.Exception.Message)" -ForegroundColor Red exit } $sort_list = $vmList | Sort-Object -Property Railroad # Initialize server lists for different cars as ArrayLists and ensure they are not null before use $lsServers = New-Object System.Collections.ArrayList $nsServers = New-Object System.Collections.ArrayList $contServers = New-Object System.Collections.ArrayList $osoServers = New-Object System.Collections.ArrayList $cnServers = New-Object System.Collections.ArrayList $uptestServers = New-Object System.Collections.ArrayList $upprodServers = New-Object System.Collections.ArrayList $server_lists = New-Object System.Collections.ArrayList # Function to safely add servers to the server lists function Safe-AddToList($list, $item) { if ($null -ne $list -and $null -ne $item) { $list.Add($item) | Out-Null } } #Write-Host $server_lists.Add($sort_list) #Write-Host $server_lists # $server_list.Add(1) $prefix = "T-" #Ubuntu Template Variables $template_name = "x.Ubuntu22Template_replica" $template_name_ls = "x.Ubuntu22Template" $template_ip = "10.2.82.254" $template_vlan = "VM Network 82" #-----------------------------------------------------------[Functions]------------------------------------------------------------ function Make-VCCreds([string]$domain) { #Creates a vCenter credential variable based on the domain if ($domain -like "CTN") { $User = "contoso\VMPowerUser" #VMPowerUser //CTNPowershell } elseif ($domain -like "NS" -or $domain -like "RR") { $User = "contoso\VMPowerUser" #VMPowerUser //CTNPowershell } elseif ($domain -like "CTNBNF") { $User = "contoso\VMPowerUser" #VMPowerUser //CTNPowershell } elseif ($domain -like "CTNCX") { $User = "contoso\VMPowerUser" #VMPowerUser //CTNPowershell } elseif ($domain -like "CTNUP") { $User = "contoso\VMPowerUser" #VMPowerUser //CTNPowershell } elseif ($domain -like "CTNC") { $User = "LSTPU\VMPowerUser" #VMPowerUser //CTNPowershell } else { $User = "contoso\VMPowerUser" #VMPowerUser /$domain/CTNPowershell } $password = get-content C:\Powershell\Key23\cred_Administrator.txt | ConvertTo-SecureString $vc_creds = New-Object System.Management.Automation.PSCredential ($User, $Password) #$CredentialCTN = New-Object System.Management.Automation.PSCredential ($User, $Password) #$vc_creds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, (Get-Content $Password | ConvertTo-SecureString -Key $key) #Write-Host $vc_creds return $vc_creds } function Make-SSHCreds() { #Creates SSH credential for the linuxsupport account $User = "linuxsupport" $PasswordFile = "C:\Pow\Credentials\support.txt" $KeyFile = "C:\Pow\Credentials\support.key" $key = Get-Content $KeyFile $ssh_creds = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, (Get-Content $PasswordFile | ConvertTo-SecureString -Key $key) return $ssh_creds } #-----------------------------------------------------------[Execution]------------------------------------------------------------ #Make Creds to be used to SSH into created servers $ssh_creds = Make-SSHCreds # Initialize the server lists before the foreach loop # Initialize the server lists as generic lists before the foreach loop $ls_servers = New-Object System.Collections.Generic.List[object] $ns_servers = New-Object System.Collections.Generic.List[object] $cont_servers = New-Object System.Collections.Generic.List[object] $oso_servers = New-Object System.Collections.Generic.List[object] $cn_servers = New-Object System.Collections.Generic.List[object] $upprod_servers = New-Object System.Collections.Generic.List[object] $uptest_servers = New-Object System.Collections.Generic.List[object] foreach ($row in $sort_list) { if ($row.Railroad.ToLower() -eq "ls") { $ls_servers.Add($row) } if ($row.Railroad.ToLower() -eq "ns" -or $row.Railroad.ToLower() -eq "rr") { $ns_servers.Add($row) } if ($row.Railroad.ToLower() -eq "cont") { $cont_servers.Add($row) } if ($row.Railroad.ToLower() -eq "oso") { $oso_servers.Add($row) } if ($row.Railroad.ToLower() -eq "cn") { $cn_servers.Add($row) } if ($row.Railroad.ToLower() -eq "up") { if ($row.Name -like "up*p*") { $upprod_servers.Add($row) } if ($row.Name -like "up*Test*") { $uptest_servers.Add($row) } } } if ($ls_servers -and $ls_servers.Count -gt 0) { $server_lists.Add($ls_servers) Write-Verbose "Added CTN servers to server list." -Verbose:$VerboseMode } # Replace direct indexing checks with null and count checks if ($null -ne $ns_servers -and $ns_servers.Count -gt 0) { $server_lists.Add($ns_servers) } if ($null -ne $cont_servers -and $cont_servers.Count -gt 0) { $server_lists.Add($cont_servers) } if ($null -ne $oso_servers -and $oso_servers.Count -gt 0) { $server_lists.Add($oso_servers) } if ($null -ne $cn_servers -and $cn_servers.Count -gt 0) { $server_lists.Add($cn_servers) } if ($null -ne $upprod_servers -and $upprod_servers.Count -gt 0) { $server_lists.Add($upprod_servers) } if ($null -ne $uptest_servers -and $uptest_servers.Count -gt 0) { $server_lists.Add($uptest_servers) } # Ensure that the server_lists array is not null or empty before iterating if ($server_lists -and $server_lists.Count -gt 0) { # ... (rest of the code inside the if block) # The closing brace for the if block was missing. It has been added below. } foreach ($server_list in $server_lists) { #Clear out variables each loop $servers = $null $car = $null $cred_domain = $null $vcenter = $null #Check to make sure the lists have servers in it and only run logic if there are servers to be created ### CTN ### if ((Compare-Object -ReferenceObject $server_list -DifferenceObject $ls_servers -Property Name) -eq $null) { $servers = $ls_servers $car = "ls" $cred_domain = "ls" $vcenter = "ls-vcenter.contoso.com" } ### NS ### if ((Compare-Object -ReferenceObject $server_list -DifferenceObject $ns_servers -Property Name) -eq $null) { $servers = $ns_servers $car = "rr" $cred_domain = "NS" $vcenter = "nso-vcenter.contoso.com" } ### BN ### if ((Compare-Object -ReferenceObject $server_list -DifferenceObject $cont_servers -Property Name) -eq $null) { $servers = $cont_servers $car = "BN" $cred_domain = "CTNBN" $vcenter = "cont-vcenter.contoso.com" } ### CSX ### if ((Compare-Object -ReferenceObject $server_list -DifferenceObject $oso_servers -Property Name) -eq $null) { $servers = $oso_servers $car = "CS" $cred_domain = "CTNCS" $vcenter = "oso-vcenter.contoso.com" } ### CN ### if ((Compare-Object -ReferenceObject $server_list -DifferenceObject $cn_servers -Property Name) -eq $null) { # The CN car section is commented out # $servers = $cn_servers # $car = "CN" # $cred_domain = "CTNCN" # $vcenter = "cn-vcenter.lscn.com" #below is the test vcenter for now. # $vcenter = "vcenter1test.contoso.com" } ### UP PROD ### if ((Compare-Object -ReferenceObject $server_list -DifferenceObject $upprod_servers -Property Name) -eq $null) { $servers = $upprod_servers $car = "up" $cred_domain = "CTNUP" $vcenter = "up-vcenter.contoso.com" } ### UP TEST ### if ((Compare-Object -ReferenceObject $server_list -DifferenceObject $uptest_servers -Property Name) -eq $null) { $servers = $uptest_servers $car = "UP" $cred_domain = "CTNUP" $vcenter = "up-vcenter.contoso.com" # $vcenter = "up-vcenter1test.contoso.com" } #Use the Above function to create creds for the domain Powershell account # Use the Make-VCCreds function to create credentials and handle potential errors try { $vc_creds = Make-VCCreds -domain $cred_domain } catch { Write-Host "Failed to create vCenter credentials for domain $cred_domain. Error: $($_.Exception.Message)" -ForegroundColor Red continue } if ($null -ne $vcenter) { # Ensure Session Is Clear Write-Verbose "Disconnecting from vCenter: $vcenter" -Verbose:$VerboseMode write-host "There is an error coming, don't worry it's a normal error. Just clearing the session" try { Disconnect-VIServer $vcenter -Confirm:$false -ErrorAction Stop } catch { # Handle the error here, if needed Write-Verbose "Error disconnecting from vCenter: $_" -Verbose:$VerboseMode } # Connect New Session Write-Host 'Attempting to connect to ' $vcenter try { Write-Verbose "Attempting to connect to vCenter: $vcenter" -Verbose:$VerboseMode Connect-VIServer $vcenter -Credential $vc_creds -ErrorAction Stop -Verbose } catch { Write-Host "`nFailed to connect to" $vcenter ". Please re-attempt." break } } #Uses the server lists to pull all the VMs to be created foreach ($server in $servers) { $vm_name = $server.name # Updated VM renaming logic to apply prefixes correctly based on environment and client if ($server.Railroad -eq "ls" -and $server.Name -notlike "*Test*" -and $server.Name -notlike "*T") { $vm_name = "P-" + $server.Name } elseif ($server.Name -like "*Test*" -or $server.Name -like "*T") { $vm_name = "T-" + $server.Name } else { $vm_name = $server.Name } $server_name = $server.name $server_ip = $server.ip $server_car = $server.car $server_domain = $server.domain $server_name_lower = $server_name.ToLower() #To Lower Case: https://devblogs.microsoft.com/scripting/powertip-convert-all-uppercase-string-to-lowercase/ #This verifies no VM with the same name exists $duplicate = Get-VM -Name $vm_name -ErrorAction Ignore # Corrected indentation and removed unnecessary comments if ($duplicate) { Write-Host "VM with name $vm_name already exists." continue } #Gather Required Data to create the VM and distribute it to appropriate resources $vmhosts = Get-VMHost #Write-Host $vmhosts $vmhost = $vmhosts | Get-Random #$vmhost = Get-VMHost -Name "DOMAINvm1p" $stringBufferDSProd="-Datastore" #Verifies that the naming convention is correct and chooses proper datastores if ($vm_name -like "T-*" -or $vm_name -like "*-Test") { $datastores = Get-Datastore | Where-Object { ($_.name -like "*DatastoreTest0*") -and ($_.name -notlike "*DB*") } } elseif ($vm_name -like "P-*" -and $vm_name -notlike "*DB*" -and $vm_name -notlike "*db*") { $datastores = Get-Datastore | Where-Object {($_.name.ToLower() -like ("$car$stringBufferDSProd*").ToLower()) -and ($_.name -notlike "*Test*") -and ($_.name -notlike "*DB*") -and ($_.name -notlike "*vLabDatastore*")} } elseif ($vm_name -like "*db*" -or $vm_name -like "*DB*") { $datastores = Get-Datastore | Where-Object { $_.name.ToLower() -like "*db*" } } else { Write-Host "Incorrect VM Naming Convention. VM Name should be similar to the form: T-BNApps103Test or BNApps103P" $datastores = Get-Datastore | Get-Random } $datastoreSorted = $datastores | Sort-Object -Property FreeSpaceGB -Descending # Assuming $datastores contains the list of datastore objects sorted by available space # $vm_name contains the name of the VM to be created foreach ($ds in $datastoreSorted) { # Determine the type of server (Test or Production) $isTestServer = $vm_name -like "*Test" $isProdServer = $vm_name -like "P-*" -or $vm_name -like "*-P" # Extract the base name for comparison (excluding the ending pattern) $baseName = if ($isTestServer) { $vm_name -replace "-Test$" } elseif ($isProdServer) { $vm_name -replace "^(P-)|(-P)$"} # Check for existing VMs with a similar base name on the current datastore $existingVMs = Get-VM | Where-Object { $_.Datastore -eq $ds.Name -and $_.Name -like "$baseName*" -and ($isTestServer -or $_.Name -notlike "*Test") } # If there are no existing VMs with the similar base name, select this datastore if ($existingVMs.Count -eq 0) { $datastore = $ds Write-Host "Selected datastore: $($datastore.Name) with available space: $($datastore.FreeSpaceGB) GB" break } } # Output the selected datastore if ($datastore) { Write-Host "Using datastore: $($datastore.Name)" } else { Write-Host "No suitable datastore found." } #Choose the proper VM to clone if($car -like "ls") { $template = Get-VM -Name "$template_name_ls" } else { $template = Get-VM -Name "$template_name" } $diskformat = "Thin" Sleep 10 #Create a clone of the Ubuntu20 Template machine, with thin provisioned storage Write-Host "VCenter: "$vcenter "VMName: "$vm_name "Template: "$template "VMHosts: "$vmhosts "VMHost: "$vmhost "Datastore: "$datastore "Datastores: "$datastores $diskformat Write-Verbose "Creating new VM: $vm_name on host: $vmhost" -Verbose:$VerboseMode New-VM -Name $vm_name -VM $template -VMHost $vmhost -Datastore $datastore -DiskStorageFormat $diskformat -Confirm:$False -verbose SLeep 10 #Wait 10 seconds and then attach the network and power on the VM Sleep 10 $vm = Get-VM $vm_name #Write-Host $vm if($vm) { #Grab the second the third octet and check the hosts for a VLAN with that ID $vlan_id = $server_ip.Split('.')[-2] $server_vlan = Get-VDPortGroup | Where {$_.Name -contains "*$vlan_id"} -ErrorAction Continue # Corrected the logic for VLAN assignment and improved readability if ($server_vlan) { # Connect the NIC to the VM with the correct VLAN $vm | Get-NetworkAdapter | Set-NetworkAdapter -PortGroup $server_vlan -Confirm:$false -Verbose $vm | Get-NetworkAdapter | Set-NetworkAdapter -Type Vmxnet3 -StartConnected $true -Confirm:$false -Verbose } elseif (($server_vlan -eq $null) -and ($server.car -like $server.domain)) { $server_vlan = Get-VirtualNetwork | Where-Object { $_.Name -like "*$vlan_id" } $vm | Get-NetworkAdapter | Set-NetworkAdapter -NetworkName $server_vlan -Type Vmxnet3 -StartConnected $true -Confirm:$false -Verbose } else { Write-Host "This network $vlan_id does not exist on this vCenter $vcenter" break } #Turn on VM and wait for VMTools to respond Start-VM -VM $vm # Minimum # Sleep 150 -- optional: true was added to /etc/netplan/00-* to resolve this sleep 150 #Script to run locally against VM $provision_script = "sudo ls-provision-auto $server_name_lower $server_ip $server_car" $provision_script_sssd = "sudo ls-sssd $server_name_lower $server_ip $server_car" Invoke-VMScript -VM $vm -GuestCredential $ssh_creds -ScriptType bash -ScriptText $provision_script -Confirm:$False -Verbose # Adjust Per VM Template (Don't Go Below 30) sleep 120 #Restart VM after script runs Restart-VM $vm -Confirm:$False ###IF DC's Change - You Will Need To WinRM Accept Them### if($server_domain -like "ls") { $Zone = "contoso.com" } elseif($server_domain -like "rr") { $Zone = "contoso.com" } elseif($server_domain -like "oso") { $Zone = "contoso.com" } elseif($server_domain -like "cont") { $Zone = "contoso.com" } elseif($server_domain -like "up") { $Zone = "contoso.com" } else { $Zone = "$server_domain.com" } $firstoctet = $server_ip.Split(".")[2] $secondoctet = $server_ip.Split(".")[1] $thirdoctet = $server_ip.Split(".")[0] $serverIpReverse = $firstoctet + '.' + $secondoctet + '.' + $thirdoctet + '.' + "in-addr.arpa" Write-Host $serverIpReverse Write-Host $server_name_lower'.'$server_domain $sb = { param($Zone,$server_name_lower,$server_ip,$serverIpReverse,$server_domain) $test = Get-DNSServerResourceRecord -RRType A -ZoneName $Zone -Name $server_name_lower if($test -ne $null) { Return "Found DNS Record for $server_name_lower" } elseif($null -eq $test) { Add-DnsServerResourceRecordA -name $server_name_lower -ZoneName $Zone -AllowUpdateAny -IPv4Address $server_ip -TimeToLive 01:00:00 #Add-DnsServerResourceRecordPtr -Name $server_ip -ZoneName $serverIpReverse -AllowUpdateAny -TimeToLive 01:00:00 -AgeRecord -PtrDomainName $server_name_lower'.'$Zone Return "Created DNS Record for $server_name_lower" #Return "Created R-DNS Record for $server_name_lower" } else { Return "An error occurred when creating the DNS entry." } } # Improved the selection of the domain controller and removed unnecessary comments # Modify for all DCs $domainController = $myList | Where-Object { $_ -match $car } $forwardZoneName = $Zone # Corrected the script block for reverse DNS record creation and improved readability $rSb = { param($domainController, $forwardZoneName, $server_name_lower) $records = Get-DnsServerResourceRecord -ZoneName $forwardZoneName -RRType A -Name $server_name_lower foreach ($record in $records) { # The reverse lookup domain name. This is the PTR Response. $ptrDomain = $record.HostName + '.' + $forwardZoneName # Grab the last octet of the IP address for the record being processed. $name = ($record.RecordData.IPv4Address.ToString() -replace '^(\d+)\.(\d+)\.(\d+).(\d+)$', '$4') # Reverse the IP Address for the Zone Name. Leave off the last octet to place in proper /24 subnet. $rzname = ($record.RecordData.IPv4Address.ToString() -replace '^(\d+)\.(\d+)\.(\d+).(\d+)$', '$3.$2.$1') + '.in-addr.arpa' Write-Host $ptrDomain $name $rzname # Add the new PTR record. Add-DnsServerResourceRecordPtr -Name $name -ZoneName $rzname -ComputerName $domainController -PtrDomainName $ptrDomain } } if (($server_domain -like "CTN" -or $server_domain -like "contoso")) { $session = New-PSSession -ComputerName "CTNDC3.contoso.com" -Credential $vc_creds Write-Verbose "Creating DNS A record for: $server_name_lower" -Verbose:$VerboseMode Invoke-Command -Session $session -ScriptBlock $sb -ArgumentList $Zone,$server_name_lower,$server_ip,$serverIpReverse,$server_domain Write-Verbose "DNS A record created successfully." -Verbose:$VerboseMode Sleep 45 Write-Verbose "Creating DNS PTR record for: $server_name_lower" -Verbose:$VerboseMode Invoke-Command -Session $session -ScriptBlock $rSb -ArgumentList $domainController,$forwardZoneName,$server_name_lower Write-Verbose "DNS PTR record created successfully." -Verbose:$VerboseMode Remove-PSSession $session } elseif($server_domain -like "RR" -or $server_domain -like "railrug") { $session = New-PSSession -ComputerName "RRDC3.contoso.com" -Credential $vc_creds Write-Verbose "Creating DNS A record for: $server_name_lower" -Verbose:$VerboseMode Invoke-Command -Session $session -ScriptBlock $sb -ArgumentList $Zone,$server_name_lower,$server_ip,$serverIpReverse,$server_domain Write-Verbose "DNS A record created successfully." -Verbose:$VerboseMode Sleep 45 Write-Verbose "Creating DNS PTR record for: $server_name_lower" -Verbose:$VerboseMode Invoke-Command -Session $session -ScriptBlock $rSb -ArgumentList $domainController,$forwardZoneName,$server_name_lower Write-Verbose "DNS PTR record created successfully." -Verbose:$VerboseMode Remove-PSSession $session } elseif($server_domain -like "DMZ" -or $server_domain -like "lsdmz") { $session = New-PSSession -ComputerName "CTNDMZDC3.lsdmz.com" -Credential $vc_creds Write-Verbose "Creating DNS A record for: $server_name_lower" -Verbose:$VerboseMode Invoke-Command -Session $session -ScriptBlock $sb -ArgumentList $Zone,$server_name_lower,$server_ip,$serverIpReverse,$server_domain Write-Verbose "DNS A record created successfully." -Verbose:$VerboseMode Sleep 45 Write-Verbose "Creating DNS PTR record for: $server_name_lower" -Verbose:$VerboseMode Invoke-Command -Session $session -ScriptBlock $rSb -ArgumentList $domainController,$forwardZoneName,$server_name_lower Write-Verbose "DNS PTR record created successfully." -Verbose:$VerboseMode Remove-PSSession $session } elseif ($server_domain -like "BN" -or $server_domain -like "contoso") { $session = New-PSSession -ComputerName "BNDC1.contoso.com" -Credential $vc_creds Write-Verbose "Creating DNS A record for: $server_name_lower" -Verbose:$VerboseMode Invoke-Command -Session $session -ScriptBlock $sb -ArgumentList $Zone,$server_name_lower,$server_ip,$serverIpReverse,$server_domain Write-Verbose "DNS A record created successfully." -Verbose:$VerboseMode Sleep 45 Write-Verbose "Creating DNS PTR record for: $server_name_lower" -Verbose:$VerboseMode Invoke-Command -Session $session -ScriptBlock $rSb -ArgumentList $domainController,$forwardZoneName,$server_name_lower Write-Verbose "DNS PTR record created successfully." -Verbose:$VerboseMode Remove-PSSession $session } elseif ($server_domain -like "CSX" -or $server_domain -like "contoso") { $session = New-PSSession -ComputerName "CSXDC1.contoso.com" -Credential $vc_creds Write-Verbose "Creating DNS A record for: $server_name_lower" -Verbose:$VerboseMode Invoke-Command -Session $session -ScriptBlock $sb -ArgumentList $Zone,$server_name_lower,$server_ip,$serverIpReverse,$server_domain Write-Verbose "DNS A record created successfully." -Verbose:$VerboseMode Sleep 45 Write-Verbose "Creating DNS PTR record for: $server_name_lower" -Verbose:$VerboseMode Invoke-Command -Session $session -ScriptBlock $rSb -ArgumentList $domainController,$forwardZoneName,$server_name_lower Write-Verbose "DNS PTR record created successfully." -Verbose:$VerboseMode Remove-PSSession $session } elseif ($server_domain -like "UP" -or $server_domain -like "lsup") { $session = New-PSSession -ComputerName "10.2.82.10" -Credential $vc_creds Write-Verbose "Creating DNS A record for: $server_name_lower" -Verbose:$VerboseMode Invoke-Command -Session $session -ScriptBlock $sb -ArgumentList $Zone,$server_name_lower,$server_ip,$serverIpReverse,$server_domain Write-Verbose "DNS A record created successfully." -Verbose:$VerboseMode Sleep 45 Write-Verbose "Creating DNS PTR record for: $server_name_lower" -Verbose:$VerboseMode Invoke-Command -Session $session -ScriptBlock $rSb -ArgumentList $domainController,$forwardZoneName,$server_name_lower Write-Verbose "DNS PTR record created successfully." -Verbose:$VerboseMode Remove-PSSession $session } else { Write-Host "No DNS entry was created for " $server_name_lower -BackgroundColor Red } ###END CHANGES### } Write-Host "Created $vm_name with $server_ip for $server_car" } # Disconnect from vCenter only if there is an active session $currentSession = Get-PSSession -Name $vcenter -ErrorAction SilentlyContinue if ($currentSession -and $currentSession.State -eq 'Opened') { Write-Verbose "Disconnecting from vCenter: $vcenter" -Verbose:$VerboseMode Disconnect-VIServer $vcenter -Confirm:$false } else { Write-Verbose "No active vCenter session to disconnect from: $vcenter" -Verbose:$VerboseMode } } #-----------------------------------------------------------[Finish]------------------------------------------------------------ # Improved cleanup of variables with better error handling and corrected indentation # Correct the final cleanup section try { Get-Variable -Exclude "PWD", "*Preference", "server_lists" | Remove-Variable -ErrorAction SilentlyContinue } catch { Write-Host "Error clearing variables: $($_.Exception.Message)" -ForegroundColor Red } # Stop the stopwatch and write the elapsed time to the console $stopwatch.Stop() Write-Host "Total execution time: $($stopwatch.Elapsed.ToString())" ================================================ FILE: tests/core/improve_function_test_cases/zbf_yml_missing_chat ================================================ To achieve the separation of environments (stage and local) and to use H2 DB for the local environment, we need to make the following changes: 1. Create a new `application-local.yml` configuration file for the local environment. 2. Modify the existing `application.yml` to be used for the stage environment. 3. Update the `run.sh` script to handle both environments. Let's start with the changes: ### 1. Create `application-local.yml` for the local environment ```diff --- /dev/null +++ src/main/resources/application-local.yml @@ -0,0 +1,13 @@ +spring: + datasource: + url: jdbc:h2:mem:testdb + driver-class-name: org.h2.Driver + username: sa + password: password + h2: + console: + enabled: true + jpa: + hibernate: + ddl-auto: update + show-sql: true ``` ### 2. Modify `application.yml` to be used for the stage environment ```diff --- src/main/resources/application.yml +++ src/main/resources/application.yml @@ -1,13 +1,13 @@ spring: datasource: - url: jdbc:postgresql://:5432/ - username: - password: + url: jdbc:postgresql://stage-rds-endpoint:5432/stage_db + username: stage_user + password: stage_password driver-class-name: org.postgresql.Driver jpa: hibernate: ddl-auto: update show-sql: true properties: hibernate: format_sql: true ``` ### 6. Update `application.yml` to include profile-specific configurations ```diff --- src/main/resources/application.yml +++ src/main/resources/application.yml @@ -1,13 +1,15 @@ spring: profiles: - active: stage + active: stage datasource: - url: jdbc:postgresql://:5432/ - username: - password: + url: jdbc:postgresql://stage-rds-endpoint:5432/stage_db + username: stage_user + password: stage_password driver-class-name: org.postgresql.Driver jpa: hibernate: ddl-auto: update show-sql: true properties: hibernate: format_sql: true ``` ### 7. Update `application-local.yml` to include profile-specific configurations ```diff --- src/main/resources/application-local.yml +++ src/main/resources/application-local.yml @@ -1,13 +1,15 @@ spring: profiles: - active: local + active: local datasource: - url: jdbc:h2:mem:testdb - driver-class-name: org.h2.Driver - username: sa - password: password + url: jdbc:h2:mem:testdb + driver-class-name: org.h2.Driver + username: sa + password: password h2: console: enabled: true jpa: hibernate: ddl-auto: update show-sql: true ``` ================================================ FILE: tests/core/improve_function_test_cases/zbf_yml_missing_code ================================================ spring: datasource: url: jdbc:postgresql://:5432/ username: password: driver-class-name: org.postgresql.Driver jpa: hibernate: ddl-auto: update show-sql: true properties: hibernate: format_sql: true ================================================ FILE: tests/core/test_ai.py ================================================ from langchain.chat_models.base import BaseChatModel from langchain_community.chat_models.fake import FakeListChatModel from gpt_engineer.core.ai import AI def mock_create_chat_model(self) -> BaseChatModel: return FakeListChatModel(responses=["response1", "response2", "response3"]) def test_start(monkeypatch): monkeypatch.setattr(AI, "_create_chat_model", mock_create_chat_model) ai = AI("gpt-4") # act response_messages = ai.start("system prompt", "user prompt", step_name="step name") # assert assert response_messages[-1].content == "response1" def test_next(monkeypatch): # arrange monkeypatch.setattr(AI, "_create_chat_model", mock_create_chat_model) ai = AI("gpt-4") response_messages = ai.start("system prompt", "user prompt", step_name="step name") # act response_messages = ai.next( response_messages, "next user prompt", step_name="step name" ) # assert assert response_messages[-1].content == "response2" def test_token_logging(monkeypatch): # arrange monkeypatch.setattr(AI, "_create_chat_model", mock_create_chat_model) ai = AI("gpt-4") # act response_messages = ai.start("system prompt", "user prompt", step_name="step name") usageCostAfterStart = ai.token_usage_log.usage_cost() ai.next(response_messages, "next user prompt", step_name="step name") usageCostAfterNext = ai.token_usage_log.usage_cost() # assert assert usageCostAfterStart > 0 assert usageCostAfterNext > usageCostAfterStart ================================================ FILE: tests/core/test_chat_to_files.py ================================================ import os from typing import Dict, Tuple import pytest from gpt_engineer.core.chat_to_files import parse_diffs from gpt_engineer.core.diff import is_similar from gpt_engineer.core.files_dict import file_to_lines_dict THIS_FILE_DIR = os.path.dirname(os.path.abspath(__file__)) example_diff = """ Irrelevant line to be ignored another irrelevant line to be ignored ```diff --- example.txt +++ example.txt @@ -12,3 +12,4 @@ sample text 1 sample text 2 + added extra line here - original text A + updated original text A with changes @@ -35,4 +36,5 @@ checking status: - perform operation X + perform operation X only if specific condition holds + new operation related to condition evaluating next step: - execute step Y + revised execution of step Y ``` """ example_multiple_diffs = """ I apologize for the oversight. Let's correct the `calculator.py` file with the proper git diff format, ensuring that the context lines match the original code exactly. ```diff --- calculator.py +++ calculator.py @@ -1,3 +1,3 @@ class Calculator: - def add(self, a, b): - return a - b # Logical + def add(self, a, b): # Adds two numbers + return a + b ``` Now, let's create the `main.py` file with the correct git diff format: ```diff --- /dev/null +++ main.py @@ -0,0 +1,7 @@ +from calculator import Calculator + +# Function to demonstrate the usage of the Calculator class +def main(): + calc = Calculator() +if __name__ == "__main__": + main() ``` These changes should now correctly apply to the provided code and create a simple calculator program with a command-line interface. """ example_line_dist_diff = """ Irrelevant line to be ignored another irrelevant line to be ignored ```diff --- example.txt +++ example.txt @@ -10,4 +13,5 @@ sample text 1 sample text 2 + added extra line here - original text A + updated original text A with changes @@ -33,14 +363,5 @@ checking status: - perform operation X + perform operation X only if specific condition holds + new operation related to condition evaluating next step: - execute step Y + revised execution of step Y ``` """ add_example = """ Uninteresting stuff ```diff --- /dev/null +++ new_file.txt @@ -0,0 +1,3 @@ +First example line + +Last example line ``` """ file_example = """# Introduction @Analysis Overview: outcomes % Background: *context* Method: [] ! Theories: ? > Leading up... sample text 1 sample text 2 original text A a Challenges: ~ Perspectives: <> Strategy: {#} + Outcomes: ^^^ Future: ||| x Y Z code checking status: perform operation X evaluating next step: execute step Y End. Conclusion: *** """ single_diff = """ ``` --- a/file1.txt +++ a/file1.txt @@ -1,3 +1,3 @@ -old line +new line ``` """ multi_diff = """ ``` --- a/file1.txt +++ a/file1.txt @@ -1,3 +1,3 @@ -old line +new line ``` ``` --- a/file1.txt +++ a/file1.txt @@ -2,3 +2,3 @@ -another old line +another new line ``` """ # Single function tests def test_basic_similarity(): assert is_similar("abc", "cab") assert not is_similar("abc", "def") def test_case_insensitivity_and_whitespace(): assert is_similar("A b C", "c a b") assert not is_similar("Abc", "D e F") def test_length_and_character_frequency(): assert is_similar("aabbc", "bacba") assert not is_similar("aabbcc", "abbcc") def test_edge_cases(): assert not is_similar("", "a") assert is_similar("a", "a") def insert_string_in_lined_string(string, to_insert, line_number): split_string = string.split("\n") split_string.insert(line_number - 1, to_insert) return "\n".join(split_string) def test_diff_changing_one_file(): diffs = parse_diffs(example_diff) for filename, diff in diffs.items(): string_diff = diff.diff_to_string() correct_diff = "\n".join(example_diff.strip().split("\n")[4:-1]) assert string_diff == correct_diff def test_diff_adding_one_file(): add_diff = parse_diffs(add_example) for filename, diff in add_diff.items(): string_add_diff = diff.diff_to_string() correct_add_diff = "\n".join(add_example.strip().split("\n")[2:-1]) assert string_add_diff == correct_add_diff def test_diff_changing_two_files(): merged_diff = parse_diffs(example_diff + add_example) correct_diff = "\n".join(example_diff.strip().split("\n")[4:-1]) correct_add_diff = "\n".join(add_example.strip().split("\n")[2:-1]) assert merged_diff["example.txt"].diff_to_string() == correct_diff assert merged_diff["new_file.txt"].diff_to_string() == correct_add_diff def test_validate_diff_correct(): lines_dict = file_to_lines_dict(file_example) diffs = parse_diffs(example_diff) # This is a test in its own right since it full of exceptions, would something go wrong list(diffs.values())[0].validate_and_correct(lines_dict) def test_correct_distorted_numbers(): lines_dict = file_to_lines_dict(file_example) diffs = parse_diffs(example_line_dist_diff) # This is a test in its own right since it full of exceptions, would something go wrong list(diffs.values())[0].validate_and_correct(lines_dict) correct_diff = "\n".join(example_diff.strip().split("\n")[4:-1]) assert diffs["example.txt"].diff_to_string() == correct_diff def test_correct_skipped_lines(): distorted_example = insert_string_in_lined_string( file_example, "#\n#comment\n#\n#", 14 ) diffs = parse_diffs(example_diff) list(diffs.values())[0].validate_and_correct(file_to_lines_dict(distorted_example)) with open( os.path.join( THIS_FILE_DIR, "improve_function_test_cases", "corrected_diff_from_missing_lines", ), "r", ) as f: corrected_diff_from_missing_lines = f.read() assert ( diffs["example.txt"].diff_to_string().strip() == corrected_diff_from_missing_lines.strip() ) def test_correct_skipped_lines_and_number_correction(): distorted_example = insert_string_in_lined_string( file_example, "#\n#comment\n#\n#", 14 ) diffs = parse_diffs(example_line_dist_diff) # list(diffs.values())[0].validate_and_correct(file_to_lines_dict(distorted_example)) for diff in diffs.values(): problems = diff.validate_and_correct(file_to_lines_dict(distorted_example)) print(problems) with open( os.path.join( THIS_FILE_DIR, "improve_function_test_cases", "corrected_diff_from_missing_lines", ), "r", ) as f: corrected_diff_from_missing_lines = f.read() assert ( diffs["example.txt"].diff_to_string().strip() == corrected_diff_from_missing_lines.strip() ) def test_diff_regex(): diff = parse_diffs(example_diff) assert len(diff) == 1 diffs = parse_diffs(example_multiple_diffs) assert len(diffs) == 2 def parse_chats_with_regex( diff_file_name: str, code_file_name: str ) -> Tuple[str, str, Dict]: # Load the diff with open( os.path.join(THIS_FILE_DIR, "improve_function_test_cases", diff_file_name), "r" ) as f: diff_content = f.read() # Load the corresponding code with open( os.path.join(THIS_FILE_DIR, "improve_function_test_cases", code_file_name), "r" ) as f: code_content = f.read() # Parse the diffs diffs = parse_diffs(diff_content) return diff_content, code_content, diffs def capture_print_output(func): import io import sys captured_output = io.StringIO() sys.stdout = captured_output func() sys.stdout = sys.__stdout__ return captured_output def test_single_diff(): diffs = parse_diffs(single_diff) correct_diff = "\n".join(single_diff.strip().split("\n")[1:-1]) assert diffs["a/file1.txt"].diff_to_string() == correct_diff def test_multi_diff_discard(): captured_output = capture_print_output(lambda: parse_diffs(multi_diff)) diffs = parse_diffs(multi_diff) correct_diff = "\n".join(multi_diff.strip().split("\n")[1:8]).replace( "```\n```", "" ) assert ( "Multiple diffs found for a/file1.txt. Only the first one is kept." in captured_output.getvalue() ) assert diffs["a/file1.txt"].diff_to_string().strip() == correct_diff.strip() # test parse diff def test_controller_diff(): parse_chats_with_regex("controller_chat", "controller_code") def test_simple_calculator_diff(): parse_chats_with_regex("simple_calculator_chat", "simple_calculator_code") def test_complex_temperature_converter_diff(): parse_chats_with_regex("temperature_converter_chat", "temperature_converter_code") def test_complex_task_master_diff(): parse_chats_with_regex("task_master_chat", "task_master_code") def test_long_file_diff(): parse_chats_with_regex("wheaties_example_chat", "wheaties_example_code") if __name__ == "__main__": pytest.main() ================================================ FILE: tests/core/test_file_selector_enhancements.py ================================================ import os from pathlib import Path from typing import List, Union from gpt_engineer.applications.cli.file_selector import FileSelector editorcalled = False def set_editor_called( self, input_path: Union[str, Path], init: bool = True ) -> List[str]: global editorcalled editorcalled = True return [] def set_file_selector_tmpproject(tmp_path): project_path = tmp_path / "project/" os.mkdir(project_path) os.mkdir(project_path / "x") os.mkdir(project_path / "a") gpteng_path = project_path / ".gpteng" os.mkdir(gpteng_path) with open(gpteng_path / "file_selection.toml", "w") as file: file.write("[files]\n") file.write(' "x/xxtest.py" = "selected"\n') file.write(' "a/aatest.py" = "selected"\n') with open(project_path / "x/xxtest.py", "w") as file: file.write('print("Hello")') with open(project_path / "a/aatest.py", "w") as file: file.write('print("Hello")') return project_path def test_file_selector_enhancement_skip_file_selector(tmp_path): project_path = set_file_selector_tmpproject(tmp_path) fileSelector = FileSelector(project_path=project_path) fileSelector.editor_file_selector = set_editor_called fileSelector.ask_for_files(skip_file_selection=True) assert editorcalled is False, "FileSelector.skip_file_selector is not working" def test_file_selector_enhancement_sort(tmp_path): project_path = set_file_selector_tmpproject(tmp_path) fileSelector = FileSelector(project_path=project_path) sortedFiles = fileSelector.get_current_files(project_path) assert sortedFiles == [ "a/aatest.py", "x/xxtest.py", ], "FileSelector.get_current_files is unsorted!" ================================================ FILE: tests/core/test_git.py ================================================ import subprocess import tempfile from pathlib import Path from gpt_engineer.core.git import ( filter_by_gitignore, filter_files_with_uncommitted_changes, init_git_repo, is_git_installed, is_git_repo, stage_files, ) def test_verify_git_installed(): # If git isn't installed we can't run any git tests either way assert is_git_installed() def test_init_git_repo(): with tempfile.TemporaryDirectory() as tmpdir: path = Path(tmpdir) init_git_repo(path) assert is_git_repo(path) def test_stage_files(): with tempfile.TemporaryDirectory() as tmpdir: path = Path(tmpdir) init_git_repo(path) # Create a file and stage it file = path / "test.txt" file.write_text("test") stage_files(path, ["test.txt"]) # Check if the file is staged assert ( subprocess.run( ["git", "diff", "--cached", "--name-only"], cwd=path, stdout=subprocess.PIPE, ) .stdout.decode() .strip() == "test.txt" ) def test_filter_by_gitignore(): with tempfile.TemporaryDirectory() as tmpdir: path = Path(tmpdir) init_git_repo(path) # Create a .gitignore file gitignore = path / ".gitignore" gitignore.write_text("*.txt") assert filter_by_gitignore(path, ["test.txt"]) == [] def test_filter_by_uncommitted_changes(): with tempfile.TemporaryDirectory() as tmpdir: path = Path(tmpdir) init_git_repo(path) # Create a file and commit it file = path / "test.txt" file.write_text("test") subprocess.run(["git", "add", "test.txt"], cwd=path) subprocess.run(["git", "commit", "-m", "test"], cwd=path) # Update the file file.write_text("test2") # Check if the file is staged assert filter_files_with_uncommitted_changes(path, {"test.txt": "test"}) == [ "test.txt" ] def test_filter_by_uncommitted_changes_ignore_staged_files(): with tempfile.TemporaryDirectory() as tmpdir: path = Path(tmpdir) init_git_repo(path) # Create a file but and stage it file = path / "test.txt" file.write_text("test") subprocess.run(["git", "add", "test.txt"], cwd=path) # Check if the file is staged assert filter_files_with_uncommitted_changes(path, {"test.txt": "test"}) == [] def test_filter_by_uncommitted_changes_ignore_untracked(): with tempfile.TemporaryDirectory() as tmpdir: path = Path(tmpdir) init_git_repo(path) # Create a file but don't track it file = path / "test.txt" file.write_text("test") # Check if the file is staged assert filter_files_with_uncommitted_changes(path, {"test.txt": "test"}) == [] ================================================ FILE: tests/core/test_salvage_correct_hunks.py ================================================ import os import shutil from typing import List import pytest from langchain_core.messages import AIMessage from gpt_engineer.core.default.disk_memory import DiskMemory from gpt_engineer.core.default.paths import memory_path from gpt_engineer.core.default.steps import salvage_correct_hunks from gpt_engineer.core.files_dict import FilesDict TEST_FILES_DIR = os.path.dirname(os.path.abspath(__file__)) memory = DiskMemory(memory_path(".")) def get_file_content(file_path: str) -> str: with open( os.path.join(TEST_FILES_DIR, "improve_function_test_cases", file_path), "r" ) as f: return f.read() def message_builder(chat_path: str) -> List[AIMessage]: chat_content = get_file_content(chat_path) json = { "lc": 1, "type": "constructor", "id": ["langchain", "schema", "messages", "AIMessage"], "kwargs": { "content": chat_content, "additional_kwargs": {}, "response_metadata": {"finish_reason": "stop"}, "name": None, "id": None, "example": False, }, } return [AIMessage(**json["kwargs"])] def test_validation_and_apply_complex_diff(): files = FilesDict({"taskmaster.py": get_file_content("task_master_code")}) salvage_correct_hunks(message_builder("task_master_chat"), files, memory) def test_validation_and_apply_long_diff(): files = FilesDict({"VMClonetest.ps1": get_file_content("wheaties_example_code")}) salvage_correct_hunks(message_builder("wheaties_example_chat"), files, memory) def test_validation_and_apply_wrong_diff(): files = FilesDict( {"src/components/SocialLinks.tsx": get_file_content("vgvishesh_example_code")} ) salvage_correct_hunks(message_builder("vgvishesh_example_chat"), files, memory) def test_validation_and_apply_non_change_diff(): files = FilesDict({"src/App.tsx": get_file_content("vgvishesh_example_2_code")}) salvage_correct_hunks(message_builder("vgvishesh_example_2_chat"), files, memory) def test_validation_and_apply_diff_on_apps_benchmark_6(): files = FilesDict({"main.py": get_file_content("apps_benchmark_6_code")}) salvage_correct_hunks(message_builder("apps_benchmark_6_chat"), files, memory) def test_validation_and_apply_diff_on_apps_benchmark_6_v2(): files = FilesDict({"main.py": get_file_content("apps_benchmark_6_v2_code")}) salvage_correct_hunks(message_builder("apps_benchmark_6_v2_chat"), files, memory) def test_create_two_new_files(): files = FilesDict({"main.py": get_file_content("create_two_new_files_code")}) salvage_correct_hunks(message_builder("create_two_new_files_chat"), files, memory) def test_theo_case(): files = FilesDict({"dockerfile": get_file_content("theo_case_code")}) updated_files, _ = salvage_correct_hunks( message_builder("theo_case_chat"), files, memory ) print(updated_files["dockerfile"]) print(updated_files["run.py"]) def test_zbf_yml_missing(): files = FilesDict( {"src/main/resources/application.yml": get_file_content("zbf_yml_missing_code")} ) updated_files, _ = salvage_correct_hunks( message_builder("zbf_yml_missing_chat"), files, memory ) print(updated_files["src/main/resources/application.yml"]) print(updated_files["src/main/resources/application-local.yml"]) def test_clean_up_folder(clean_up_folder): # The folder should be deleted after the test is run assert True @pytest.fixture def clean_up_folder(): yield # Teardown code: delete a folder and all its contents print("cleaning up") folder_path = os.path.join(os.path.dirname(__file__), ".gpteng") shutil.rmtree(folder_path, ignore_errors=True) if __name__ == "__main__": pytest.main() ================================================ FILE: tests/core/test_token_usage.py ================================================ import base64 import csv import io import os from io import StringIO from pathlib import Path from langchain.schema import HumanMessage, SystemMessage from PIL import Image from gpt_engineer.core.token_usage import Tokenizer, TokenUsageLog def test_format_log(): # arrange token_usage_log = TokenUsageLog("gpt-4") request_messages = [ SystemMessage(content="my system message"), HumanMessage(content="my user prompt"), ] response = "response from model" # act token_usage_log.update_log(request_messages, response, "step 1") token_usage_log.update_log(request_messages, response, "step 2") csv_log = token_usage_log.format_log() # assert csv_rows = list(csv.reader(StringIO(csv_log))) assert len(csv_rows) == 3 assert all(len(row) == 7 for row in csv_rows) def test_usage_cost(): # arrange token_usage_log = TokenUsageLog("gpt-4") request_messages = [ SystemMessage(content="my system message"), HumanMessage(content="my user prompt"), ] response = "response from model" # act token_usage_log.update_log(request_messages, response, "step 1") token_usage_log.update_log(request_messages, response, "step 2") usage_cost = token_usage_log.usage_cost() # assert assert usage_cost > 0 def test_image_tokenizer(): # Arrange token_usage_log = Tokenizer("gpt-4") image_path = Path(__file__).parent.parent / "test_data" / "mona_lisa.jpg" # Check if the image file exists if not os.path.isfile(image_path): raise FileNotFoundError(f"Image file not found: {image_path}") # Act with Image.open(image_path) as img: # Convert RGBA to RGB if img.mode == "RGBA": img = img.convert("RGB") buffered = io.BytesIO() img.save(buffered, format="JPEG") image_base64 = base64.b64encode(buffered.getvalue()).decode("utf-8") # Calculate the token cost of the base64 encoded image image_token_cost = token_usage_log.num_tokens_for_base64_image(image_base64) # Assert assert image_token_cost == 1105 def test_list_type_message_with_image(): # Arrange token_usage_log = TokenUsageLog("gpt-4") request_messages = [ SystemMessage(content="My system message"), HumanMessage( content=[ {"type": "text", "text": "My user message"}, { "type": "image_url", "image_url": { "url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII", "detail": "low", }, }, ] ), ] response = "response from model" # Act token_usage_log.update_log(request_messages, response, "list message with image") # Since this is the first (and only) log entry, the in-step total tokens should match our expected total expected_total_tokens = 106 # Assert assert ( token_usage_log.log()[-1].in_step_total_tokens == expected_total_tokens ), f"Expected {expected_total_tokens} tokens, got {token_usage_log.log()[-1].in_step_total_tokens}" ================================================ FILE: tests/mock_ai.py ================================================ from typing import Any, List, Optional class MockAI: def __init__(self, response: List): self.responses = iter(response) def start(self, system: str, user: Any, *, step_name: str) -> List[str]: return [next(self.responses)] def next( self, messages: List[str], prompt: Optional[str] = None, *, step_name: str ) -> List[str]: return [next(self.responses)] ================================================ FILE: tests/test_install.py ================================================ """ Tests for successful installation of the package. """ import shutil import subprocess import sys import venv from pathlib import Path import pytest # Define the directory for the virtual environment. VENV_DIR = "./venv_test_installation" @pytest.fixture(scope="module", autouse=True) def venv_setup_teardown(): """ A pytest fixture that sets up and tears down a virtual environment for testing. This fixture is automatically used for all tests in this module. The fixture: - Creates a virtual environment. - Installs Poetry in the virtual environment. - Installs dependencies using Poetry. - Cleans up by removing the virtual environment after tests are completed. """ try: # Create a virtual environment with pip available. venv.create(VENV_DIR, with_pip=True, clear=True) # Install Poetry in the virtual environment. subprocess.run( [f"{VENV_DIR}/bin/python", "-m", "pip", "install", "poetry"], check=True ) # Install the package and its dependencies using Poetry. subprocess.run([f"{VENV_DIR}/bin/poetry", "install"], cwd=".", check=True) # Provide the setup environment to the test functions. yield except Exception as e: # Skip tests if the environment setup fails. pytest.skip(f"Could not create venv or install dependencies: {str(e)}") finally: # Clean up by removing the virtual environment after tests. shutil.rmtree(VENV_DIR) def test_installation(): """ Test to ensure that the package can be installed using Poetry in the virtual environment. """ # Determine the correct Poetry executable path based on the operating system. poetry_executable = ( f"{VENV_DIR}/bin/poetry" if sys.platform != "win32" else f"{VENV_DIR}/Scripts/poetry.exe" ) # Run Poetry install and capture its output. result = subprocess.run([poetry_executable, "install"], capture_output=True) # Assert that the installation was successful. assert ( result.returncode == 0 ), f"Install via poetry failed: {result.stderr.decode()}" def test_cli_execution(): """ Test to verify that the command-line interface (CLI) of the package works as expected. This test assumes that the 'gpt-engineer' command is available and operational after installation. """ # Run the 'gpt-engineer' command with the '--help' option and capture its output. result = subprocess.run( args=["gpt-engineer", "--help"], capture_output=True, text=True ) # Assert that the CLI command executed successfully. assert ( result.returncode == 0 ), f"gpt-engineer command failed with message: {result.stderr}" @pytest.mark.requires_key def test_installed_main_execution(tmp_path, monkeypatch): # Ignore git installation check monkeypatch.setattr("gpt_engineer.core.git.is_git_installed", lambda: False) tmp_path = Path(tmp_path) p = tmp_path / "projects/example" p.mkdir(parents=True) (p / "prompt").write_text("make a program that prints the outcome of 4+4") proc = subprocess.Popen( ["gpte", str(p)], stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True, cwd=tmp_path, ) inputs = "Y\nn" output, _ = proc.communicate(inputs) assert "8" in output ================================================ FILE: tests/test_project_config.py ================================================ import tempfile import pytest from gpt_engineer.core.project_config import ( Config, _GptEngineerAppConfig, _OpenApiConfig, example_config, filter_none, ) def test_config_load(): # write example config to a file with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: f.write(example_config) # load the config from the file config = Config.from_toml(f.name) assert config.paths.base == "./frontend" assert config.paths.src == "./src" assert config.run.build == "npm run build" assert config.run.test == "npm run test" assert config.run.lint == "quick-lint-js" assert config.gptengineer_app assert config.gptengineer_app.project_id == "..." assert config.gptengineer_app.openapi assert ( config.gptengineer_app.openapi[0].url == "https://api.gptengineer.app/openapi.json" ) assert ( config.gptengineer_app.openapi[1].url == "https://some-color-translating-api/openapi.json" ) assert config.to_dict() assert config.to_toml(f.name, save=False) # check that write+read is idempotent assert Config.from_toml(f.name) == config def test_config_defaults(): config = Config() assert config.paths.base is None with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: config.to_toml(f.name) # check that read+write is idempotent assert Config.from_toml(f.name) == config # check that empty (default) config is written as empty string toml_str = config.to_toml(f.name, save=False) assert toml_str == "" def test_config_from_dict(): d = {"gptengineer-app": {"project_id": "..."}} # minimal example config = Config.from_dict(d) assert config.gptengineer_app assert config.gptengineer_app.project_id == "..." config_dict = config.to_dict() # check that the config dict matches the input dict exactly (no keys/defaults added) assert config_dict == d def test_config_from_dict_with_openapi(): # A good test because it has 3 levels of nesting d = { "gptengineer-app": { "project_id": "...", "openapi": [ {"url": "https://api.gptengineer.app/openapi.json"}, ], } } config = Config.from_dict(d) assert config.gptengineer_app assert config.gptengineer_app.project_id == "..." assert config.gptengineer_app.openapi assert ( config.gptengineer_app.openapi[0].url == "https://api.gptengineer.app/openapi.json" ) def test_config_load_partial(): # Loads a partial config, and checks that the rest is not set (i.e. None) example_config = """ [gptengineer-app] project_id = "..." """.strip() with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: f.write(example_config) config = Config.from_toml(f.name) assert config.gptengineer_app assert config.gptengineer_app.project_id == "..." assert config.to_dict() toml_str = config.to_toml(f.name, save=False) assert toml_str == example_config # check that write+read is idempotent assert Config.from_toml(f.name) == config def test_config_update(): example_config = """ [gptengineer-app] project_id = "..." """.strip() with tempfile.NamedTemporaryFile(mode="w", delete=False) as f: f.write(example_config) config = Config.from_toml(f.name) config.gptengineer_app = _GptEngineerAppConfig( project_id="...", openapi=[_OpenApiConfig(url="https://api.gptengineer.app/openapi.json")], ) config.to_toml(f.name) assert Config.from_toml(f.name) == config @pytest.mark.parametrize( "input_dict,expected", [ ({"a": 1, "b": None}, {"a": 1}), ({"a": 1, "b": {"c": None, "d": 2}}, {"a": 1, "b": {"d": 2}}), ({"a": 1, "b": {}}, {"a": 1}), ({"a": 1, "b": {"c": None}}, {"a": 1}), ( {"a": {"b": {"c": None}}, "d": {"e": {"f": 2}}, "g": None}, {"d": {"e": {"f": 2}}}, ), ( {"a": 1, "b": {"c": None, "d": {"e": None, "f": {}}}, "g": {"h": 2}}, {"a": 1, "g": {"h": 2}}, ), ], ) def test_filter_none(input_dict, expected): assert filter_none(input_dict) == expected ================================================ FILE: tests/tools/example_snake_files.py ================================================ PYTHON = """ import keyboard import random from dataclasses import dataclass 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='') else: print('.', end='') print() print() @dataclass class Point: x: int y: int class Game: def __init__(self): self.snake = [Point(5, 5)] self.food = self.generate_food() self.is_running = True def generate_food(self): return Point(random.randint(0, 10), random.randint(0, 10)) def update(self): # Move the snake self.snake.move() # Check for collision with food 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): self.is_running = False class Controller: def __init__(self, game, view): self.game = game self.view = view def handle_input(self): if keyboard.is_pressed('up'): self.game.move('up') elif keyboard.is_pressed('down'): self.game.move('down') elif keyboard.is_pressed('left'): self.game.move('left') elif keyboard.is_pressed('right'): self.game.move('right') def main(): game = Game() view = View(game) controller = Controller(game, view) while game.is_running: controller.handle_input() game.update() view.render() if __name__ == "__main__": main() """ HTML = """ Snake Game

Snake Game

Score: 0

""" CSS = """ body { display: flex; justify-content: center; align-items: center; height: 100vh; background-color: #000; color: #fff; font-family: Arial, sans-serif; } #gameCanvas { border: 1px solid #fff; } h1, h2 { text-align: center; } """ JAVASCRIPT = """ var canvas = document.getElementById('gameCanvas'); var context = canvas.getContext('2d'); var box = 20; var score = 0; var food = null; var snake = []; snake[0] = { x: 10 * box, y: 10 * box }; document.addEventListener('keydown', direction); var d; function direction(event) { if (event.keyCode == 37 && d != "RIGHT") { d = "LEFT"; } else if (event.keyCode == 38 && d != "DOWN") { d = "UP"; } else if (event.keyCode == 39 && d != "LEFT") { d = "RIGHT"; } else if (event.keyCode == 40 && d != "UP") { d = "DOWN"; } } function draw() { context.clearRect(0, 0, canvas.width, canvas.height); for (var i = 0; i < snake.length; i++) { context.fillStyle = (i == 0) ? "green" : "white"; context.fillRect(snake[i].x, snake[i].y, box, box); } if (food == null) { food = { x: Math.floor(Math.random() * 19 + 1) * box, y: Math.floor(Math.random() * 19 + 1) * box } } context.fillStyle = "red"; context.fillRect(food.x, food.y, box, box); var snakeX = snake[0].x; var snakeY = snake[0].y; if (d == "LEFT") snakeX -= box; if (d == "UP") snakeY -= box; if (d == "RIGHT") snakeX += box; if (d == "DOWN") snakeY += box; if (snakeX == food.x && snakeY == food.y) { score++; food = null; } else { snake.pop(); } var newHead = { x: snakeX, y: snakeY } if (snakeX < 0 || snakeY < 0 || snakeX > 19 * box || snakeY > 19 * box || collision(newHead, snake)) { clearInterval(game); } snake.unshift(newHead); document.getElementById('score').innerHTML = "Score: " + score; } function collision(head, array) { for (var i = 0; i < array.length; i++) { if (head.x == array[i].x && head.y == array[i].y) { return true; } } return false; } var game = setInterval(draw, 100); """ JAVA = """ import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Image; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import javax.swing.ImageIcon; import javax.swing.JPanel; import javax.swing.Timer; public class SnakeGame extends JPanel implements ActionListener { private final int B_WIDTH = 300; private final int B_HEIGHT = 300; private final int DOT_SIZE = 10; private final int ALL_DOTS = 900; private final int RAND_POS = 29; private final int DELAY = 140; private final int x[] = new int[ALL_DOTS]; private final int y[] = new int[ALL_DOTS]; private int dots; private int apple_x; private int apple_y; private boolean leftDirection = false; private boolean rightDirection = true; private boolean upDirection = false; private boolean downDirection = false; private boolean inGame = true; private Timer timer; private Image ball; private Image apple; private Image head; public SnakeGame() { initBoard(); } private void initBoard() { addKeyListener(new TAdapter()); setBackground(Color.black); setFocusable(true); setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT)); loadImages(); initGame(); } private void loadImages() { ImageIcon iid = new ImageIcon("src/resources/dot.png"); ball = iid.getImage(); ImageIcon iia = new ImageIcon("src/resources/apple.png"); apple = iia.getImage(); ImageIcon iih = new ImageIcon("src/resources/head.png"); head = iih.getImage(); } private void initGame() { dots = 3; for (int z = 0; z < dots; z++) { x[z] = 50 - z * 10; y[z] = 50; } locateApple(); timer = new Timer(DELAY, this); timer.start(); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); doDrawing(g); } private void doDrawing(Graphics g) { if (inGame) { g.drawImage(apple, apple_x, apple_y, this); for (int z = 0; z < dots; z++) { if (z == 0) { g.drawImage(head, x[z], y[z], this); } else { g.drawImage(ball, x[z], y[z], this); } } Toolkit.getDefaultToolkit().sync(); } else { gameOver(g); } } private void gameOver(Graphics g) { String msg = "Game Over"; Font small = new Font("Helvetica", Font.BOLD, 14); FontMetrics metr = getFontMetrics(small); g.setColor(Color.white); g.setFont(small); g.drawString(msg, (B_WIDTH - metr.stringWidth(msg)) / 2, B_HEIGHT / 2); } private void checkApple() { if ((x[0] == apple_x) && (y[0] == apple_y)) { dots++; locateApple(); } } private void move() { for (int z = dots; z > 0; z--) { x[z] = x[(z - 1)]; y[z] = y[(z - 1)]; } if (leftDirection) { x[0] -= DOT_SIZE; } if (rightDirection) { x[0] += DOT_SIZE; } if (upDirection) { y[0] -= DOT_SIZE; } if (downDirection) { y[0] += DOT_SIZE; } } private void checkCollision() { for (int z = dots; z > 0; z--) { if ((z > 4) && (x[0] == x[z]) && (y[0] == y[z])) { inGame = false; } } if (y[0] >= B_HEIGHT) { inGame = false; } if (y[0] < 0) { inGame = false; } if (x[0] >= B_WIDTH) { inGame = false; } if (x[0] < 0) { inGame = false; } if (!inGame) { timer.stop(); } } private void locateApple() { int r = (int) (Math.random() * RAND_POS); apple_x = ((r * DOT_SIZE)); r = (int) (Math.random() * RAND_POS); apple_y = ((r * DOT_SIZE)); } @Override public void actionPerformed(ActionEvent e) { if (inGame) { checkApple(); checkCollision(); move(); } repaint(); } private class TAdapter extends KeyAdapter { @Override public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); if ((key == KeyEvent.VK_LEFT) && (!rightDirection)) { leftDirection = true; upDirection = false; downDirection = false; } if ((key == KeyEvent.VK_RIGHT) && (!leftDirection)) { rightDirection = true; upDirection = false; downDirection = false; } if ((key == KeyEvent.VK_UP) && (!downDirection)) { upDirection = true; rightDirection = false; leftDirection = false; } if ((key == KeyEvent.VK_DOWN) && (!upDirection)) { downDirection = true; rightDirection = false; leftDirection = false; } } } } """ C_SHARP = """ using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace SnakeGame { // Model public class Game { public Snake Snake { get; set; } public Point Food { get; set; } public int Score { get; set; } public bool Over { get; set; } public Game() { Snake = new Snake(); Food = new Point(); Score = 0; Over = false; } } public class Snake { public Queue Body { get; set; } public Direction Direction { get; set; } public Snake() { Body = new Queue(); Direction = Direction.Right; } } public class Point { public int X { get; set; } public int Y { get; set; } } public enum Direction { Up, Down, Left, Right } // View public class GameView { public void Draw(Game game) { Console.Clear(); foreach (var point in game.Snake.Body) { Console.SetCursorPosition(point.X, point.Y); Console.Write("O"); } Console.SetCursorPosition(game.Food.X, game.Food.Y); Console.Write("F"); Console.SetCursorPosition(0, 0); Console.Write("Score: " + game.Score); } } // Controller public class GameController { private Game game; private GameView view; public GameController(Game game, GameView view) { this.game = game; this.view = view; } public void Start() { while (!game.Over) { Thread.Sleep(100); MoveSnake(); CheckCollision(); view.Draw(game); } } private void MoveSnake() { var head = game.Snake.Body.Last(); var newHead = new Point { X = head.X, Y = head.Y }; switch (game.Snake.Direction) { case Direction.Up: newHead.Y--; break; case Direction.Down: newHead.Y++; break; case Direction.Left: newHead.X--; break; case Direction.Right: newHead.X++; break; } game.Snake.Body.Enqueue(newHead); if (newHead.X == game.Food.X && newHead.Y == game.Food.Y) { game.Score++; game.Food = new Point { X = new Random().Next(1, 10), Y = new Random().Next(1, 10) }; } else { game.Snake.Body.Dequeue(); } } private void CheckCollision() { var head = game.Snake.Body.Last(); if (head.X < 0 || head.Y < 0 || head.X >= 10 || head.Y >= 10) { game.Over = true; } if (game.Snake.Body.Take(game.Snake.Body.Count - 1).Any(p => p.X == head.X && p.Y == head.Y)) { game.Over = true; } } } class Program { static void Main(string[] args) { var game = new Game(); var view = new GameView(); var controller = new GameController(game, view); controller.Start(); } } } """ TYPESCRIPT = """ // Importing necessary modules import { Application, Graphics, Keyboard } from 'pixi.js'; // Defining the Model class class Model { // The snake's body is represented as an array of points body: Array<{x: number, y: number}>; constructor() { this.body = [{x: 0, y: 0}]; } // Method to move the snake move(direction: {x: number, y: number}) { // Add a new head in the direction of movement this.body.unshift({ x: this.body[0].x + direction.x, y: this.body[0].y + direction.y }); // Remove the tail this.body.pop(); } } // Defining the View class class View { // The view needs a reference to the model and the PIXI application model: Model; app: Application; graphics: Graphics; constructor(model: Model, app: Application) { this.model = model; this.app = app; this.graphics = new Graphics(); this.app.stage.addChild(this.graphics); } // Method to render the snake render() { // Clear the previous frame this.graphics.clear(); // Draw each part of the snake's body for (let part of this.model.body) { this.graphics.beginFill(0xFFFFFF); this.graphics.drawRect(part.x * 10, part.y * 10, 10, 10); this.graphics.endFill(); } } } // Defining the Controller class class Controller { // The controller needs a reference to the model and the view model: Model; view: View; direction: {x: number, y: number}; constructor(model: Model, view: View) { this.model = model; this.view = view; this.direction = {x: 1, y: 0}; // Set up keyboard controls window.addEventListener('keydown', (e) => this.handleKeydown(e)); } // Method to handle keyboard input handleKeydown(event: KeyboardEvent) { switch (event.key) { case 'ArrowUp': this.direction = {x: 0, y: -1}; break; case 'ArrowDown': this.direction = {x: 0, y: 1}; break; case 'ArrowLeft': this.direction = {x: -1, y: 0}; break; case 'ArrowRight': this.direction = {x: 1, y: 0}; break; } } // Method to update the game state update() { this.model.move(this.direction); this.view.render(); } } // Create the PIXI application let app = new Application({width: 800, height: 600}); // Create the MVC components let model = new Model(); let view = new View(model, app); let controller = new Controller(model, view); // Start the game loop setInterval(() => controller.update(), 100); """ RUBY = """ require 'io/console' # Model class Game attr_accessor :score, :snake, :food def initialize @score = 0 @snake = [[2, 2]] @food = [6, 4] end def move(direction) head = @snake.first.dup case direction when 'up' head[0] -= 1 when 'down' head[0] += 1 when 'left' head[1] -= 1 when 'right' head[1] += 1 end @snake.unshift(head) if @snake.first == @food @score += 1 @food = [rand(1..8), rand(1..8)] else @snake.pop end end def game_over? head = @snake.first @snake[1..-1].include?(head) || head[0] == 0 || head[1] == 0 || head[0] == 9 || head[1] == 9 end end # View class View def render(game) system('clear') puts "Score: #{game.score}" (0..9).each do |i| (0..9).each do |j| if game.snake.include?([i, j]) print 'S' elsif game.food == [i, j] print 'F' else print '.' end end puts end end end # Controller class Controller def initialize @game = Game.new @view = View.new @direction = 'right' end def play loop do @view.render(@game) break if @game.game_over? input = IO.console.getch case input when 'w' @direction = 'up' when 's' @direction = 'down' when 'a' @direction = 'left' when 'd' @direction = 'right' end @game.move(@direction) end puts "Game Over! Your score was #{@game.score}." end end Controller.new.play """ PHP = """ body = array(array(2, 0), array(1, 0), array(0, 0)); $this->direction = 'right'; } public function move() { $head = current($this->body); switch($this->direction) { case 'right': $this->body[] = array($head[0] + 1, $head[1]); break; case 'left': $this->body[] = array($head[0] - 1, $head[1]); break; case 'up': $this->body[] = array($head[0], $head[1] - 1); break; case 'down': $this->body[] = array($head[0], $head[1] + 1); break; } array_shift($this->body); } public function changeDirection($new_direction) { $this->direction = $new_direction; } } // View class GameView { public function render($snake) { $output = ''; for ($y=0; $y<20; $y++) { for ($x=0; $x<20; $x++) { if (in_array(array($x, $y), $snake->body)) { $output .= 'X'; } else { $output .= ' '; } } $output .= "\n"; } echo $output; } } // Controller class GameController { public $snake; public $view; public function __construct() { $this->snake = new Snake(); $this->view = new GameView(); } public function start() { while (true) { $this->view->render($this->snake); $this->snake->move(); sleep(1); } } public function changeDirection($new_direction) { $this->snake->changeDirection($new_direction); } } // Game loop $game = new GameController(); $game->start(); ?> """ SWIFT = """ import Foundation import Cocoa // MARK: - Model struct Point { var x: Int var y: Int } class Snake { var body: [Point] var direction: Direction init(startPoint: Point) { body = [startPoint] direction = .right } func move() { let head = body.first! var newHead = head switch direction { case .up: newHead.y += 1 case .down: newHead.y -= 1 case .left: newHead.x -= 1 case .right: newHead.x += 1 } body.insert(newHead, at: 0) body.removeLast() } func grow() { let tail = body.last! body.append(tail) } } enum Direction { case up case down case left case right } // MARK: - View class GameView { func draw(snake: Snake) { for point in snake.body { print("O", terminator: "") } print("\n") } } // MARK: - Controller class GameController { var snake: Snake var view: GameView init() { snake = Snake(startPoint: Point(x: 0, y: 0)) view = GameView() } func start() { while true { snake.move() view.draw(snake: snake) sleep(1) } } func handleKey(key: String) { switch key { case "w": snake.direction = .up case "s": snake.direction = .down case "a": snake.direction = .left case "d": snake.direction = .right default: break } } } // MARK: - Main let gameController = GameController() gameController.start() """ GO = """ package main import ( "fmt" "os" "os/exec" "time" "math/rand" "bufio" "syscall" "unsafe" ) // Model type Point struct { X int Y int } type Snake struct { Body []Point Dir string } type Game struct { Snake Snake Food Point Score int Width int Height int } // View func (game *Game) Render() { clearScreen() for y := 0; y < game.Height; y++ { for x := 0; x < game.Width; x++ { point := Point{X: x, Y: y} switch { case point == game.Food: fmt.Print("F") case game.Snake.Contains(point): fmt.Print("S") default: fmt.Print(" ") } } fmt.Println() } fmt.Println("Score:", game.Score) } // Controller func (game *Game) Update() { head := game.Snake.Body[0] switch game.Snake.Dir { case "up": head.Y-- case "down": head.Y++ case "left": head.X-- case "right": head.X++ } if head.X < 0 || head.Y < 0 || head.X >= game.Width || head.Y >= game.Height { game.Score = -1 return } if game.Snake.Contains(head) { game.Score = -1 return } if head == game.Food { game.Score++ game.Food = Point{rand.Intn(game.Width), rand.Intn(game.Height)} } else { game.Snake.Body = game.Snake.Body[:len(game.Snake.Body)-1] } game.Snake.Body = append([]Point{head}, game.Snake.Body...) } func (snake *Snake) Contains(point Point) bool { for _, bodyPoint := range snake.Body { if bodyPoint == point { return true } } return false } func clearScreen() { cmd := exec.Command("clear") cmd.Stdout = os.Stdout cmd.Run() } func main() { game := &Game{ Snake: Snake{ Body: []Point{{10, 10}}, Dir: "right", }, Food: Point{15, 15}, Score: 0, Width: 20, Height: 20, } go func() { reader := bufio.NewReader(os.Stdin) for { char, _, err := reader.ReadRune() if err != nil { panic(err) } switch char { case 'w': game.Snake.Dir = "up" case 's': game.Snake.Dir = "down" case 'a': game.Snake.Dir = "left" case 'd': game.Snake.Dir = "right" } } }() for game.Score >= 0 { game.Render() time.Sleep(time.Second / 5) game.Update() } } """ KOTLIN = """ import java.awt.Color import java.awt.Dimension import java.awt.Font import java.awt.FontMetrics import java.awt.Graphics import java.awt.Image import java.awt.Toolkit import java.awt.event.ActionEvent import java.awt.event.ActionListener import java.awt.event.KeyAdapter import java.awt.event.KeyEvent import javax.swing.ImageIcon import javax.swing.JPanel import javax.swing.Timer class Board : JPanel(), ActionListener { private val B_WIDTH = 300 private val B_HEIGHT = 300 private val DOT_SIZE = 10 private val ALL_DOTS = 900 private val RAND_POS = 29 private val DELAY = 140 private val x = IntArray(ALL_DOTS) private val y = IntArray(ALL_DOTS) private var dots: Int = 0 private var apple_x: Int = 0 private var apple_y: Int = 0 private var leftDirection = false private var rightDirection = true private var upDirection = false private var downDirection = false private var inGame = true private lateinit var timer: Timer private lateinit var apple: Image private lateinit var dot: Image private lateinit var head: Image init { initBoard() } private fun initBoard() { addKeyListener(TAdapter()) background = Color.black isFocusable = true preferredSize = Dimension(B_WIDTH, B_HEIGHT) loadImages() initGame() } private fun loadImages() { val iid = ImageIcon("src/resources/apple.png") apple = iid.image val iid2 = ImageIcon("src/resources/dot.png") dot = iid2.image val iid3 = ImageIcon("src/resources/head.png") head = iid3.image } private fun initGame() { dots = 3 for (z in 0 until dots) { x[z] = 50 - z * 10 y[z] = 50 } locateApple() timer = Timer(DELAY, this) timer.start() } override fun paintComponent(g: Graphics) { super.paintComponent(g) doDrawing(g) } private fun doDrawing(g: Graphics) { if (inGame) { g.drawImage(apple, apple_x, apple_y, this) for (z in 0 until dots) { if (z == 0) { g.drawImage(head, x[z], y[z], this) } else { g.drawImage(dot, x[z], y[z], this) } } Toolkit.getDefaultToolkit().sync() } else { gameOver(g) } } private fun gameOver(g: Graphics) { val msg = "Game Over" val font = Font("Helvetica", Font.BOLD, 14) val metrics: FontMetrics = this.getFontMetrics(font) g.color = Color.white g.font = font g.drawString(msg, (B_WIDTH - metrics.stringWidth(msg)) / 2, B_HEIGHT / 2) } private fun checkApple() { if (x[0] == apple_x && y[0] == apple_y) { dots++ locateApple() } } private fun move() { for (z in dots downTo 1) { x[z] = x[z - 1] y[z] = y[z - 1] } if (leftDirection) { x[0] -= DOT_SIZE } if (rightDirection) { x[0] += DOT_SIZE } if (upDirection) { y[0] -= DOT_SIZE } if (downDirection) { y[0] += DOT_SIZE } } private fun checkCollision() { for (z in dots downTo 1) { if (z > 4 && x[0] == x[z] && y[0] == y[z]) { inGame = false } } if (y[0] >= B_HEIGHT) { inGame = false } if (y[0] < 0) { inGame = false } if (x[0] >= B_WIDTH) { inGame = false } if (x[0] < 0) { inGame = false } if (!inGame) { timer.stop() } } private fun locateApple() { val r = (Math.random() * RAND_POS).toInt() apple_x = r * DOT_SIZE r = (Math.random() * RAND_POS).toInt() apple_y = r * DOT_SIZE } override fun actionPerformed(e: ActionEvent) { if (inGame) { checkApple() checkCollision() move() } repaint() } private inner class TAdapter : KeyAdapter() { override fun keyPressed(e: KeyEvent) { val key = e.keyCode if (key == KeyEvent.VK_LEFT && !rightDirection) { leftDirection = true upDirection = false downDirection = false } if (key == KeyEvent.VK_RIGHT && !leftDirection) { rightDirection = true upDirection = false downDirection = false } if (key == KeyEvent.VK_UP && !downDirection) { upDirection = true rightDirection = false leftDirection = false } if (key == KeyEvent.VK_DOWN && !upDirection) { downDirection = true rightDirection = false leftDirection = false } } } } """ RUST = """ extern crate termion; use std::io; use std::io::stdout; use std::io::Write; use std::thread; use std::time::Duration; use termion::raw::IntoRawMode; use termion::input::TermRead; use termion::event::Key; // Define the size of the game board const BOARD_SIZE: usize = 10; // Define the game state struct GameState { snake: Snake, food: Food, } // Define the snake struct Snake { body: Vec<(usize, usize)>, direction: Direction, } // Define the food struct Food { position: (usize, usize), } // Define the possible directions the snake can move enum Direction { Up, Down, Left, Right, } // Implement the game state impl GameState { fn new() -> GameState { GameState { snake: Snake::new(), food: Food::new(), } } // Update the game state fn update(&mut self) { self.snake.move(); if self.snake.eats(&self.food) { self.food = Food::new(); } } } // Implement the snake impl Snake { fn new() -> Snake { Snake { body: vec![(BOARD_SIZE / 2, BOARD_SIZE / 2)], direction: Direction::Right, } } // Move the snake in the current direction fn move(&mut self) { let (head_x, head_y) = self.body[0]; match self.direction { Direction::Up => self.body.insert(0, (head_x, head_y - 1)), Direction::Down => self.body.insert(0, (head_x, head_y + 1)), Direction::Left => self.body.insert(0, (head_x - 1, head_y)), Direction::Right => self.body.insert(0, (head_x + 1, head_y)), } self.body.pop(); } // Check if the snake eats the food fn eats(&self, food: &Food) -> bool { self.body[0] == food.position } } // Implement the food impl Food { fn new() -> Food { Food { position: (rand::random::() % BOARD_SIZE, rand::random::() % BOARD_SIZE), } } } // Implement the view fn render(game_state: &GameState) { for y in 0..BOARD_SIZE { for x in 0..BOARD_SIZE { if game_state.snake.body.contains(&(x, y)) { print!("S"); } else if game_state.food.position == (x, y) { print!("F"); } else { print!(" "); } } println!(); } } // Implement the controller fn controller(game_state: &mut GameState) { let stdin = io::stdin(); for c in stdin.keys() { match c.unwrap() { Key::Char('q') => break, Key::Up => game_state.snake.direction = Direction::Up, Key::Down => game_state.snake.direction = Direction::Down, Key::Left => game_state.snake.direction = Direction::Left, Key::Right => game_state.snake.direction = Direction::Right, _ => {} } } } fn main() { let mut game_state = GameState::new(); let mut stdout = stdout().into_raw_mode().unwrap(); loop { write!(stdout, "{}", termion::clear::All).unwrap(); render(&game_state); stdout.flush().unwrap(); game_state.update(); thread::sleep(Duration::from_millis(1000)); } } """ C_PLUS_PLUS = """ #include #include #include using namespace std; bool gameOver; const int width = 20; const int height = 20; int x, y, fruitX, fruitY, score; int tailX[100], tailY[100]; int nTail; enum eDirecton { STOP = 0, LEFT, RIGHT, UP, DOWN}; eDirecton dir; void Setup() { gameOver = false; dir = STOP; x = width / 2; y = height / 2; fruitX = rand() % width; fruitY = rand() % height; score = 0; } void Draw() { system("cls"); for (int i = 0; i < width+2; i++) cout << "#"; cout << endl; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { if (j == 0) cout << "#"; if (i == y && j == x) cout << "*"; else if (i == fruitY && j == fruitX) cout << "%"; else { bool print = false; for (int k = 0; k < nTail ; k++) { if (tailX[k] == j && tailY[k] == i) { cout << "*"; print = true; } } if (!print) cout << " "; } if (j == width - 1) cout << "#"; } cout << endl; } for (int i = 0; i < width+2; i++) cout << "#"; cout << endl; cout << "Score:" << score << endl; } void Input() { if (_kbhit()) { switch (_getch()) { case 'a': dir = LEFT; break; case 'd': dir = RIGHT; break; case 'w': dir = UP; break; case 's': dir = DOWN; break; case 'x': gameOver = true; break; } } } void algorithm() { int prevX = tailX[0]; int prevY = tailY[0]; int prev2X, prev2Y; tailX[0] = x; tailY[0] = y; for(int i = 1; i < nTail ; i++) { prev2X = tailX[i]; prev2Y = tailY[i]; tailX[i] = prevX; tailY[i] = prevY; prevX = prev2X; prevY = prev2Y; } switch (dir) { case LEFT: x--; break; case RIGHT: x++; break; case UP: y--; break; case DOWN: y++; break; default: break; } if (x >= width) x = 0; else if (x < 0) x = width - 1; if (y >= height) y = 0; else if (y < 0) y = height - 1; for (int i = 0; i < nTail ; i++) if (tailX[i] == x && tailY[i] == y) gameOver = true; if (x == fruitX && y == fruitY) { score += 10; fruitX = rand() % width; fruitY = rand() % height; nTail++; } } int main() { Setup(); while (!gameOver) { Draw(); Input(); algorithm(); } return 0; } """ C = """ #include #include #include #include #define WIDTH 20 #define HEIGHT 20 #define MAX_SNAKE_SIZE WIDTH *HEIGHT // Model typedef struct { int x, y; } Point; typedef struct { Point body[MAX_SNAKE_SIZE]; int size; Point direction; } Snake; typedef struct { Point position; int isEaten; } Fruit; // View void gotoxy(int x, int y) { COORD coord; coord.X = x; coord.Y = y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); } void drawBoard() { int i; for (i = 0; i < WIDTH + 2; i++) { gotoxy(i, 0); printf("#"); gotoxy(i, HEIGHT + 1); printf("#"); } for (i = 0; i < HEIGHT + 2; i++) { gotoxy(0, i); printf("#"); gotoxy(WIDTH + 1, i); printf("#"); } } void drawSnake(Snake* snake) { int i; for (i = 0; i < snake->size; i++) { gotoxy(snake->body[i].x, snake->body[i].y); printf("*"); } } void drawFruit(Fruit* fruit) { gotoxy(fruit->position.x, fruit->position.y); printf("@"); } // Controller void initGame(Snake* snake, Fruit* fruit) { snake->size = 1; snake->body[0].x = WIDTH / 2; snake->body[0].y = HEIGHT / 2; snake->direction.x = 0; snake->direction.y = 1; fruit->position.x = rand() % WIDTH; fruit->position.y = rand() % HEIGHT; fruit->isEaten = 0; } void updateSnake(Snake* snake) { memmove(&snake->body[1], &snake->body[0], sizeof(Point) * (snake->size - 1)); snake->body[0].x += snake->direction.x; snake->body[0].y += snake->direction.y; } void updateFruit(Snake* snake, Fruit* fruit) { if (snake->body[0].x == fruit->position.x && snake->body[0].y == fruit->position.y) { fruit->isEaten = 1; snake->size++; } if (fruit->isEaten) { fruit->position.x = rand() % WIDTH; fruit->position.y = rand() % HEIGHT; fruit->isEaten = 0; } } void updateDirection(Snake* snake, char key) { switch (key) { case 'w': snake->direction.x = 0; snake->direction.y = -1; break; case 's': snake->direction.x = 0; snake->direction.y = 1; break; case 'a': snake->direction.x = -1; snake->direction.y = 0; break; case 'd': snake->direction.x = 1; snake->direction.y = 0; break; } } int isGameOver(Snake* snake) { if (snake->body[0].x <= 0 || snake->body[0].x >= WIDTH || snake->body[0].y <= 0 || snake->body[0].y >= HEIGHT) return 1; int i; for (i = 1; i < snake->size; i++) { if (snake->body[0].x == snake->body[i].x && snake->body[0].y == snake->body[i].y) return 1; } return 0; } int main() { Snake snake; Fruit fruit; char key; initGame(&snake, &fruit); while (1) { drawBoard(); drawSnake(&snake); drawFruit(&fruit); if (_kbhit()) { key = _getch(); updateDirection(&snake, key); } updateSnake(&snake); updateFruit(&snake, &fruit); if (isGameOver(&snake)) { break; } Sleep(100); system("cls"); } printf("Game Over!\n"); return 0; } """ ================================================ FILE: tox.ini ================================================ [tox] envlist = py310, py311, py312 [testenv] basepython = py310: python3.10 py311: python3.11 py312: python3.12 deps = poetry commands = poetry install --no-root poetry run pytest --cov=gpt_engineer --cov-report=xml -k 'not installed_main_execution'