Jesse A. Green / notebook

Live demo: the DocCompiler guide library as a static, read-only snapshot (October 2026). No backend, no accounts, nothing to submit.

gpt-engineer Administrator & Developer Guide

Generated June 2026 from AntonOsika/gpt-engineer at a90fcd5

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

This guide is the deep reference for operators, integrators, and developers working with gpt-engineer — the open-source CLI that generates and improves codebases with large language models. It covers the architecture, the core library API, configuration, deployment (including Docker), security considerations, operations, and the internal pipeline in enough detail to extend or embed the tool.

It is written against gpt-engineer 0.3.1 (commit a90fcd5). For installation and day-to-day usage, see the companion User Guide.


1. Executive Summary

gpt-engineer is a Python application with two distinct layers:

  • A reusable core library (gpt_engineer/core/) that defines a small set of abstractions — an agent, a memory, and an execution environment — plus a LangChain-based LLM wrapper, a robust git-diff engine, and token accounting. The core is provider-agnostic and has no CLI dependencies.
  • A CLI application (gpt_engineer/applications/cli/) built on Typer that wires the core into an interactive terminal experience: argument parsing, interactive file selection, human-review feedback, and optional telemetry.

The defining behavior of gpt-engineer is that it not only writes code but can execute it: every generation produces a run.sh entrypoint, and the tool offers to run it. The improve workflow uses a custom unified-diff format with validation and self-correction so that LLM-produced patches apply cleanly to real files.

Attribute Value
Language Python (>=3.10,<3.13)
CLI framework Typer
LLM integration LangChain (langchain, langchain-openai, langchain-anthropic, langchain-community)
Packaging Poetry (pyproject.toml)
License MIT
Console scripts gpt-engineer, ge, gpte, bench, gpte_test_application
Persistent state File-based (.gpteng/ per project) — no database
Source size 170 files / ~245 KB of source at the documented commit

2. Architecture

2.1 Layered view

┌──────────────────────────────────────────────────────────────┐
│  CLI application layer  —  gpt_engineer/applications/cli/      │
│                                                                │
│   main.py          Typer app: parses flags, wires the agent    │
│   cli_agent.py     CliAgent: orchestrates gen + improve         │
│   file_selector.py Interactive TOML-based file picker          │
│   learning.py      Human-review capture + consent              │
│   collect.py       RudderStack telemetry (opt-in)              │
└───────────────┬──────────────────────────────────────────────┘
                │ depends on
┌───────────────▼──────────────────────────────────────────────┐
│  Core library  —  gpt_engineer/core/                          │
│                                                                │
│   ai.py            AI: LangChain chat-model wrapper            │
│   base_agent.py        ┐                                       │
│   base_memory.py       │ abstract interfaces                   │
│   base_execution_env.py│                                       │
│   version_manager.py   ┘                                       │
│   prompt.py        Prompt value object (text + images)         │
│   files_dict.py    FilesDict: {path -> content} container      │
│   chat_to_files.py Parse LLM output into files / diffs         │
│   diff.py          Hunk/Diff model + validate & correct        │
│   token_usage.py   Tokenizer + TokenUsageLog (cost)            │
│   project_config.py gpt-engineer.toml reader/writer            │
│   linting.py       black formatting                            │
│   git.py           git helpers (stage/init/ignore)             │
│   preprompts_holder.py  loads preprompts/ templates            │
│                                                                │
│   core/default/    Concrete implementations:                   │
│     simple_agent.py     SimpleAgent (library-friendly agent)   │
│     disk_memory.py      DiskMemory  (files = key/value store)  │
│     disk_execution_env.py DiskExecutionEnv (subprocess runner) │
│     file_store.py       FileStore (writes generated files)     │
│     steps.py            gen_code / gen_entrypoint / improve_fn  │
│     paths.py / constants.py  path + tuning constants           │
└───────────────┬──────────────────────────────────────────────┘
                │ uses
┌───────────────▼──────────────────────────────────────────────┐
│  preprompts/   The system prompts that define the AI's role    │
│  tools/        custom_steps.py (clarify / lite / self-heal),   │
│                supported_languages.py                          │
│  benchmark/    `bench` CLI for evaluating agents (APPS, MBPP)  │
└────────────────────────────────────────────────────────────────┘

2.2 The three core abstractions

gpt-engineer's extensibility rests on three abstract base classes in gpt_engineer/core/. Any alternative implementation can be substituted without touching the rest of the system.

Interface File Contract Default implementation
BaseAgent base_agent.py init(prompt) -> FilesDict; improve(files_dict, prompt) -> FilesDict CliAgent, SimpleAgent
BaseMemory base_memory.py A MutableMapping[str | Path, str] — keys are filenames, values are contents DiskMemory
BaseExecutionEnv base_execution_env.py run, popen, upload(FilesDict), download() -> FilesDict DiskExecutionEnv
BaseVersionManager version_manager.py snapshot(files_dict) -> str (interface only)

Note

Because the agent is parameterized by functions for code generation, improvement, and execution (code_gen_fn, improve_fn, process_code_fn), the CLI can swap behaviors at runtime — for example substituting clarified_gen/lite_gen for gen_code, or self_heal for execute_entrypoint — without subclassing.

2.3 Component inventory

Component Responsibility
AI (core/ai.py) Wraps a LangChain BaseChatModel. Selects OpenAI / Azure OpenAI / Anthropic based on model name and Azure endpoint. Handles message collapsing, serialization, streaming, vision detection, and rate-limit backoff.
ClipboardAI (core/ai.py) An AI subclass that exchanges messages via the system clipboard instead of an API call.
Prompt (core/prompt.py) Immutable value object holding prompt text, optional image URLs, and an optional entrypoint prompt. Serializes to LangChain content blocks.
FilesDict (core/files_dict.py) A dict subclass mapping filename → content, with type enforcement and to_chat() / to_log() renderers.
chat_to_files.py Parses LLM chat output into a FilesDict (fenced-code regex) and parses/apply unified diffs.
diff.py Hunk and Diff classes; validates LLM-produced diffs against the original file and self-corrects mismatches.
TokenUsageLog (core/token_usage.py) Per-step token counting via tiktoken, plus USD cost estimation for OpenAI models and image-token math for vision.
Config (core/project_config.py) Reads/writes the optional gpt-engineer.toml project file.
DiskMemory (core/default/disk_memory.py) File-backed key/value store; also archives prior run logs.
DiskExecutionEnv (core/default/disk_execution_env.py) Runs the entrypoint as a subprocess and captures output.
FileStore (core/default/file_store.py) Writes a FilesDict to the working directory; runs linting.
steps.py The generation/improvement pipeline functions (see Section 7).
custom_steps.py (tools/) Alternative pipeline functions: clarified_gen, lite_gen, self_heal.
preprompts/ Eight extensionless template files that compose the system prompts.

3. Requirements & Dependencies

3.1 Runtime requirements

Item Requirement
Python >=3.10,<3.13 (CI/docs build on 3.11)
git Optional but recommended; enables file staging and gitignore filtering
Network Outbound HTTPS to the chosen LLM provider (unless using a local model or clipboard mode)
Provider key OPENAI_API_KEY and/or ANTHROPIC_API_KEY

3.2 Key Python dependencies

Declared in pyproject.toml under [tool.poetry.dependencies]. The most architecturally significant:

Dependency Constraint Role in gpt-engineer
openai ^1.0 Underlying OpenAI client; openai.RateLimitError drives backoff
langchain >=0.1.2 Chat-model abstraction, message schema, LLM cache
langchain_openai * ChatOpenAI, AzureChatOpenAI
langchain-anthropic ^0.1.1 ChatAnthropic for Claude models
langchain-community ^0.2.0 SQLiteCache, OpenAI cost tables
typer >=0.3.2 CLI framework for main.py and benchmark/__main__.py
tiktoken >=0.0.4 Token counting
tomlkit / toml ^0.12.4 / >=0.10.2 gpt-engineer.toml and file_selection.toml
regex ^2023.12.25 Timeout-capable diff parsing
black 23.3.0 Linting/formatting of selected Python files
pyperclip ^1.8.2 Clipboard mode
pillow ^10.2.0 Image sizing for vision token math
rudder-sdk-python >=2.0.2 Opt-in telemetry
datasets ^2.17.1 Benchmark dataset loading

Dev and docs dependency groups (pytest, mypy, ruff, pre-commit, tox; and the Sphinx stack) are declared under [tool.poetry.group.dev.dependencies] and [tool.poetry.group.docs.dependencies].

Important

The dependency langchain_openai = "*" is unpinned. When reproducing a build for production, pin it (and ideally the rest of the LangChain stack) to known-good versions — LangChain's minor releases have historically moved import paths. token_usage.py already guards one such move with a try/except ImportError around get_openai_token_cost_for_model.


4. Configuration Reference

gpt-engineer has three configuration surfaces: environment variables, the optional gpt-engineer.toml project file, and the per-project file_selection.toml.

4.1 Environment variables

Variable Default Read in Purpose
OPENAI_API_KEY — main.py, ai.py OpenAI / Azure auth. Loaded from .env if unset.
ANTHROPIC_API_KEY — main.py Anthropic (Claude) auth. Loaded from .env if unset.
MODEL_NAME gpt-4o main.py Default value for --model.
OPENAI_API_VERSION 2024-05-01-preview ai.py Azure OpenAI API version.
LOCAL_MODEL unset main.py When set, prints $0.0 cost instead of computing one.
EDITOR unset file_selector.py Preferred editor for interactive file selection.
GPTE_TEST_MODE unset file_selector.py Internal: forces file selection to read from the saved TOML (used by tests).

Note

Key loading is intentionally redundant: load_env_if_needed() calls load_dotenv() and then load_dotenv(<cwd>/.env) for each key "for legacy reasons." The effect is that a .env in the current directory is always honored when the variable isn't already exported.

4.2 gpt-engineer.toml (project configuration)

An optional TOML file at the project root, parsed by Config.from_toml() in core/project_config.py. It is primarily consumed by the related gptengineer.app service but is read by the CLI's file selector when present. Full schema:

[run]
build = "npm run build"
test = "npm run test"
lint = "quick-lint-js"
# format = "..."             # also supported

[paths]
base = "./frontend"          # base directory to operate in (for monorepos)
src = "./src"                # source dir (under base) used as LLM context

[gptengineer-app]            # namespace for gptengineer.app
project_id = "..."           # required if this section is present
openapi = [                  # optional list of OpenAPI schemas used as context
    { url = "https://api.gptengineer.app/openapi.json" },
    { url = "https://some-color-translating-api/openapi.json" },
]
Section / key Type Notes
[run] build / test / lint / format string Project commands
[paths] base string Base dir for monorepos
[paths] src string Source dir, relative to base, used as context
[gptengineer-app] project_id string Required when the section exists (assertion enforced)
[gptengineer-app] openapi list of {url} OpenAPI schemas provided as LLM context

Config.to_toml() writes back only values that are explicitly set or differ from defaults, preserving the existing TOML document via tomlkit.

4.3 file_selection.toml (improve mode)

Written into <project>/.gpteng/memory/ during improve mode. Lines marked # "<path>" = "selected" are deselected; uncommenting includes the file. A [linting] section toggles black:

[linting]
"linting" = "off"     # default behaviour is linting ON

4.4 Tuning constants

Constant Value Location Effect
MAX_EDIT_REFINEMENT_STEPS 2 core/default/constants.py Diff-correction retry passes in improve mode
MAX_SELF_HEAL_ATTEMPTS 10 tools/custom_steps.py Self-heal execute/fix iterations
diff_timeout 3 (s) CLI flag → chat_to_files.parse_diffs Regex timeout for diff parsing
backoff max_tries=7, max_time=45 ai.backoff_inference Exponential backoff on RateLimitError
Claude max_tokens_to_sample 4096 ai._create_chat_model Anthropic output cap
Vision max_tokens 4096 ai._create_chat_model Vision model output cap

5. On-Disk Layout & State

gpt-engineer keeps all state on the filesystem — there is no database or external store. State for a project lives under a hidden .gpteng/ directory inside that project.

<project>/
├── prompt                         # your instructions (input)
├── <generated source files>       # output
├── run.sh                         # generated entrypoint (ENTRYPOINT_FILE)
└── .gpteng/                       # META_DATA_REL_PATH
    ├── file_selection.toml        # improve-mode file picker state
    └── memory/                    # MEMORY_REL_PATH = .gpteng/memory
        └── logs/
            ├── all_output.txt          # CODE_GEN_LOG_FILE
            ├── improve.txt             # IMPROVE_LOG_FILE
            ├── diff_errors.txt         # DIFF_LOG_FILE
            ├── debug_log_file.txt      # DEBUG_LOG_FILE
            └── gen_entrypoint_chat.txt # ENTRYPOINT_LOG_FILE

Path constants are defined in core/default/paths.py:

Constant Value
META_DATA_REL_PATH .gpteng
MEMORY_REL_PATH .gpteng/memory
ENTRYPOINT_FILE run.sh
PREPROMPTS_PATH <package>/preprompts

Other state files written outside .gpteng/:

File Location Purpose
.gpte_consent working directory Stores true if you opted into telemetry
gpt_engineer_user_id.txt system temp dir Anonymous session id for telemetry
.langchain.db working directory SQLite LLM response cache (--use_cache)
clipboard.txt working directory Last clipboard-mode payload

DiskMemory.archive_logs() rotates prior logs at the start of each run so history is preserved across invocations.


6. The AI Wrapper (core/ai.py)

The AI class is the single point of contact with language models. Understanding it is key to integrations and to supporting new providers.

6.1 Provider selection

AI._create_chat_model() chooses the LangChain chat model from the constructor arguments:

if azure_endpoint set        -> AzureChatOpenAI (uses OPENAI_API_VERSION, deployment_name=model_name)
elif "claude" in model_name  -> ChatAnthropic   (max_tokens_to_sample=4096)
elif vision                  -> ChatOpenAI       (max_tokens=4096)
else                         -> ChatOpenAI

All variants enable streaming and attach a StreamingStdOutCallbackHandler so generation appears live in the terminal.

6.2 Vision detection

vision is True when the model name contains vision-preview, or contains gpt-4-turbo without preview, or contains claude. When the active model is non-vision, the CLI strips image URLs from the prompt before sending.

6.3 Message handling

  • start(system, user, *, step_name) seeds a conversation and calls next().
  • next(messages, prompt=None, *, step_name) appends, optionally collapses consecutive same-role messages (for non-vision models), runs inference, and records token usage.
  • backoff_inference() wraps llm.invoke() with @backoff.on_exception(backoff.expo, openai.RateLimitError, max_tries=7, max_time=45).
  • serialize_messages() / deserialize_messages() persist conversation history as JSON (normalizing LangChain's stricter chunk schema).

6.4 Token accounting & cost

TokenUsageLog (in token_usage.py) counts tokens per step with a tiktoken tokenizer (cl100k_base fallback for non-GPT models), accumulates totals, and can emit a CSV log. usage_cost() returns a USD estimate only for OpenAI models (is_openai_model() checks for gpt in the name); otherwise it returns None. Vision images are costed via num_tokens_for_base64_image(), which replicates OpenAI's tile-based image token formula using Pillow to measure dimensions.

At the end of a run, main.py prints one of:

Total api cost: $  <amount>        # OpenAI model
Total api cost: $ 0.0 since we are using local LLM.   # LOCAL_MODEL set
Total tokens used:  <n>            # non-OpenAI, non-local

7. The Generation Pipeline (Internals)

The pipeline is a set of pure-ish functions in core/default/steps.py (and tools/custom_steps.py), composed by CliAgent.

7.1 System prompts (preprompts/)

The AI's behavior is defined by eight template files loaded by PrepromptsHolder. They are plain text with no extension:

Preprompt Role
roadmap Frames the task: "You will get instructions for code to write… write a very long answer."
generate Demands step-by-step reasoning, then full file output; embeds FILE_FORMAT.
file_format Defines the FILENAME + fenced-code output contract for new code.
file_format_diff Defines the strict unified-git diff contract for edits (the rules that make diffs apply cleanly).
file_format_fix Variant used when fixing errors.
improve Improve-mode framing; embeds file_format_diff.
philosophy Coding conventions (one class per file, requirements.txt for Python, package.json for Node, pytest/dataclasses, etc.).
clarify Drives clarify mode: ask one question or say "Nothing to clarify."
entrypoint Instructs the model to emit terminal commands for run.sh (no global installs, no sudo, no placeholders).

The generate system prompt is assembled as:

roadmap + generate(FILE_FORMAT := file_format) + "\nUseful to know:\n" + philosophy

and the improve system prompt swaps in improve(FILE_FORMAT := file_format_diff).

Tip

--use-custom-preprompts copies these templates into <project>/preprompts/ (via get_preprompts_path), letting a project override the AI's identity and conventions persistently. This is the supported customization seam — prefer it over forking.

7.2 Generate flow (gen_code → gen_entrypoint → execute_entrypoint)

  1. gen_code sends the generate system prompt + user prompt; parses the reply with chat_to_files_dict() (a (\S+)\n\s*```...```` regex) into a FilesDict. Logs to all_output.txt`.
  2. gen_entrypoint asks the model for a unix script that installs deps and runs the code (default instruction if no entrypoint_prompt is given), extracts fenced code into run.sh. Logs to gen_entrypoint_chat.txt.
  3. execute_entrypoint prints the script, prompts Do you want to execute this code? (Y/n), and on confirmation runs bash run.sh via the execution environment.

7.3 Improve flow (improve_fn → _improve_loop → salvage_correct_hunks)

  1. improve_fn builds a message stack: improve system prompt + the selected files (FilesDict.to_chat(), which prepends line numbers) + the user prompt. Logs uploaded files to debug_log_file.txt.
  2. _improve_loop calls the model, then salvage_correct_hunks, retrying up to MAX_EDIT_REFINEMENT_STEPS (2) times while feeding back any malformed-diff errors.
  3. salvage_correct_hunks parses diffs with parse_diffs() (timeout-bounded regex), validates each non-new-file hunk against the real file via Diff.validate_and_correct(), then applies them with apply_diffs().

7.4 Diff validation & correction (core/diff.py)

This is the most intricate part of the codebase and the reason LLM edits apply reliably. Hunk.validate_and_correct():

  • Locates the hunk's start line in the original file using a fuzzy is_similar() comparison (character-overlap ratio ≥ 0.9, whitespace/case-insensitive).
  • Detects and repairs two common LLM mistakes: skipped context lines (re-inserts them) and spurious extra lines (drops them), choosing between them by comparing forward-block similarity ratios.
  • Relabels misplaced comment lines as additions.
  • Recomputes hunk header line numbers and offsets after correction so the resulting diff is internally consistent.

Invalid hunks that cannot be salvaged are printed (Invalid Hunk NO.x) and removed rather than aborting the whole patch.

7.5 Alternative steps (tools/custom_steps.py)

Function Substitutes for Behavior
clarified_gen gen_code Loops on the clarify preprompt, gathering answers until the model says "Nothing to clarify," then generates.
lite_gen gen_code Single ai.start() call with the raw prompt + file_format; no roadmap/philosophy framing.
self_heal execute_entrypoint Runs run.sh; on non-zero (and non-2) exit, feeds stdout/stderr back through improve_fn, up to 10 times.

8. Security

Caution

gpt-engineer's core function is to write and execute code produced by a language model. This is powerful and inherently risky. The guidance below is essential reading before running it on any machine that holds data or credentials you care about.

8.1 Arbitrary code execution (by design)

execute_entrypoint() runs bash run.sh — commands authored by the LLM. There is a Do you want to execute this code? (Y/n) confirmation, but self-heal mode bypasses per-attempt confirmation and executes up to 10 times automatically. Mitigations:

  • Run inside a container or disposable VM (see Section 9). The bundled Docker image isolates execution to a mounted project directory.
  • Always read run.sh before confirming. Decline (n) when in doubt.
  • Avoid --self-heal on hosts with sensitive state.

8.2 Path traversal in file writing

FileStore.push() (and DiskMemory) write files using paths that originate from LLM output. A community report (issue #1346) describes a path-traversal risk where LLM-generated filenames could escape the working directory and write arbitrary files. Treat the project directory as a trust boundary:

  • Run generation as an unprivileged user.
  • Prefer container execution where the writable mount is scoped to /project.
  • Review generated file paths, not just file contents, before execution.

Warning

This behavior is not unique to one mode — any flow that writes a FilesDict to disk relies on the LLM's filenames. Containerization is the most robust mitigation.

8.3 Telemetry & data handling

applications/cli/collect.py can send "learning" data (prompt, model, config, logs, and your review answers) to a RudderStack endpoint to help improve the tool. Important facts for operators:

  • It is opt-in. check_collection_consent() only sends data if .gpte_consent contains true; otherwise the user is prompted.
  • The RudderStack write_key and dataPlaneUrl are hardcoded in collect.py.
  • Disable by answering n, or by deleting .gpte_consent. For fleet deployments, pre-create .gpte_consent absent/empty, or strip collect.py calls.
  • Payloads are truncated to RudderStack's 32 KB event limit (collect_learnings trims oversized logs).

Important

In regulated or air-gapped environments, audit and disable telemetry explicitly. Logs sent can include prompt text and session logs.

8.4 Secrets

API keys are read from the environment or a .env file. The .env.template ships placeholder values only. Standard hygiene applies: keep .env out of version control, scope keys narrowly, and prefer short-lived keys for shared runners.

8.5 Docker permission note

docker/entrypoint.sh runs chown -R nobody:nogroup and chmod -R 777 on generated files (except the prompt file) so host users can access container output. World-writable output is convenient but loose — tighten it if the host is multi-tenant.


9. Deployment (Docker)

Running gpt-engineer in Docker is the recommended way to contain code execution.

9.1 Image

docker/Dockerfile is a two-stage build on python:3.11-slim:

  • Builder stage installs tk, tcl, curl, git, then pip install --no-cache-dir -e ..
  • Final stage copies site-packages and binaries from the builder, copies the app, and sets ENTRYPOINT ["bash", "/app/entrypoint.sh"].

docker/entrypoint.sh invokes gpt-engineer /project "$@" against a mounted /project directory, then fixes output permissions.

9.2 Build & run with the Docker CLI

docker build --rm -t gpt-engineer -f docker/Dockerfile .

docker run -it --rm \
  -e OPENAI_API_KEY="YOUR_OPENAI_KEY" \
  -v ./your-project:/project \
  gpt-engineer
Running gpt-engineer in /project
...
Do you want to execute this code? (Y/n)

The mounted directory must contain a prompt file. Any flags after the image name are passed straight through to gpt-engineer.

9.3 Docker Compose

docker-compose.yml defines a single gpt-engineer service with stdin_open/tty for interactivity, an env_file: .env, and a volume mapping ./projects/example:/project:

docker compose -f docker-compose.yml build
docker compose run --rm gpt-engineer

Edit the volumes entry to point at your own project, and provide the API key via .env or an environment: override.

9.4 Debugging the image

docker run -it --entrypoint /bin/bash gpt-engineer

This opens a shell inside the container so you can inspect the environment manually.


10. Operations

10.1 Running locally (Makefile)

The Makefile provides three convenience targets:

Target Action
make help Print usage
make install poetry install + install pre-commit hooks + farewell message
make run <name> poetry run gpt-engineer projects/<name>
make cloc Count lines of code (excludes vendored/benchmark dirs)

10.2 Logs & diagnostics

Per-project logs live in <project>/.gpteng/memory/logs/. The most useful for incident triage:

  • debug_log_file.txt — uploaded files, prompt, and the full console capture from improve mode (including stack traces).
  • diff_errors.txt — per-hunk validation problems from the diff engine.
  • all_output.txt / improve.txt — full step transcripts.

gpte --sysinfo prints OS, OS version, architecture, Python version, and the full pip list, then exits — attach this to bug reports.

10.3 Cost & token control

  • --use_cache enables SQLiteCache(.langchain.db) so identical requests are free on rerun.
  • --lite reduces prompt overhead for small tasks.
  • Token totals and (for OpenAI) USD cost print at the end of each run; the per-step CSV is available via TokenUsageLog.format_log().

10.4 Rate limits

Inference is wrapped in exponential backoff (max_tries=7, max_time=45 s) on openai.RateLimitError. Persistent throttling beyond that window surfaces as a RateLimitError to the user.


11. Benchmarking (bench)

gpt-engineer installs a separate bench console script (gpt_engineer/benchmark/__main__.py, a Typer app) for evaluating agent implementations against public datasets.

bench PATH_TO_AGENT [BENCH_CONFIG] [--yaml-output FILE] [--verbose]
Argument / option Default Purpose
PATH_TO_AGENT (required) A Python file exposing a default_config_agent() function
BENCH_CONFIG benchmark/default_bench_config.toml Selects which benchmark tasks to run
--yaml-output none Write per-task results to a YAML file
--verbose off Verbose output

Currently supported benchmarks are APPS and MBPP (loaded via the datasets dependency). The agent under test is imported dynamically with importlib. A starter agent template is available in the project's gpte-bench-template repository.

Note

bench dynamically imports and executes the agent module you point it at. Only run it against agent code you trust.


12. Code Quality & Conventions

Aspect Detail
Formatter black (pinned 23.3.0), config in [tool.black] (target-version = py310)
Linter ruff (select = ["F","E","W","I001"], ignores E501, E722)
Type checking mypy 1.3.0
Pre-commit black, ruff --fix, plus check-toml, check-yaml, detect-private-key, EOF/whitespace fixers; fail_fast: true
Tests pytest; marker requires_key flags tests needing a real OPENAI_API_KEY (deselect with -m "not requires_key")
Docstrings NumPy-style throughout; enforced culturally (see sweep.yaml rules)
Docs Sphinx on Read the Docs (.readthedocs.yaml, Python 3.11, poetry install --with docs, docs/create_api_rst.py pre-build)

The codebase has good test coverage around the fragile parts: tests/core/ exercises the diff engine (test_salvage_correct_hunks.py), chat_to_files, token usage, and the disk-backed memory/execution environments; tests/applications/cli/ covers the CLI agent, file collection, consent, and the main entrypoint across all modes.


13. Extending gpt-engineer

Common extension points, in order of how cleanly they're supported:

  1. Override the system prompts. Use --use-custom-preprompts (or ship a preprompts/ folder) to change conventions, language defaults, or the AI's role — no code changes.
  2. Swap step functions. Provide your own code_gen_fn, improve_fn, or process_code_fn to CliAgent/SimpleAgent. This is how clarify/lite/self-heal are implemented.
  3. Implement a BaseExecutionEnv. Replace DiskExecutionEnv to run generated code in a sandbox, remote host, or container instead of a local subprocess. The interface (run, popen, upload, download) is deliberately small.
  4. Implement a BaseMemory. Replace DiskMemory to store project state somewhere other than the local filesystem.
  5. Add a provider. Extend AI._create_chat_model() with a new branch returning the appropriate LangChain chat model, and update vision/is_openai_model heuristics as needed.

Tip

Embedding gpt-engineer as a library is best done through SimpleAgent (core/default/simple_agent.py) rather than the CLI's CliAgent, since SimpleAgent has no CLI/telemetry/file-selection coupling.


14. Potential Improvements & Tech Debt

Observations drawn directly from the source at this commit:

  • Unpinned langchain_openai = "*". A floating major dependency in a project whose token-cost code already works around one LangChain import move. Pin the LangChain stack for reproducible builds.
  • Path-traversal exposure (issue #1346). File writes trust LLM-supplied paths. A sanitizing/normalization layer in FileStore.push() would harden the default (non-Docker) path.
  • Hardcoded telemetry credentials. The RudderStack write_key lives in source. A config/env toggle (or a build flag to compile it out) would suit enterprise deployments better than the current opt-in file.
  • Provider/vision detection by substring. Model routing keys off substrings like "claude", "gpt-4-turbo", and "vision-preview". New model names (e.g., OpenRouter routing, Gemini, Ollama — issues #1321, #1319) don't fit cleanly; a provider registry would scale better.
  • run.sh-centric execution. The pipeline assumes a unix bash entrypoint; Windows execution leans on WSL/Docker. A pluggable entrypoint strategy would broaden native support.
  • World-writable Docker output (chmod -R 777 in entrypoint.sh) trades safety for convenience.

15. Quick Reference

Console scripts (from pyproject.toml)

Command Target Purpose
gpt-engineer, ge, gpte applications.cli.main:app Main CLI
bench benchmark.__main__:app Agent benchmarking
gpte_test_application tests.caching_main:app Test harness (internal)

Key paths

Path Meaning
<project>/prompt User instructions (input)
<project>/run.sh Generated entrypoint
<project>/.gpteng/memory/logs/ Step transcripts
<project>/.gpteng/memory/file_selection.toml Improve-mode selection
.gpte_consent Telemetry opt-in flag
.langchain.db LLM response cache

Tuning knobs

Knob Default Where
--diff_timeout 3 s CLI
MAX_EDIT_REFINEMENT_STEPS 2 constants.py
MAX_SELF_HEAL_ATTEMPTS 10 custom_steps.py
backoff 7 tries / 45 s ai.py

Environment variables

OPENAI_API_KEY · ANTHROPIC_API_KEY · MODEL_NAME · OPENAI_API_VERSION · LOCAL_MODEL · EDITOR · GPTE_TEST_MODE