Skip to main content

A coding agent built on LLM

Project description

llm-coding-agent

PyPI Tests Changelog License

A coding agent built on LLM

Built by Fable 5

The first working alpha was built using the following prompts:

Write a spec.md for this project - it will depend on the latest “llm” alpha from PyPI and implement a Claude code style coding agent complete with tools for reading and editing files and executing commands

Then:

Commit the spec, then build it using red/green TDD in a series of sensible commits (each with passing tests and updated docs) - occasionally manually test it using the OpenAI API key in your environment

Installation

Install this library using pip (the --pre flag is needed while this depends on an LLM alpha release):

pip install --pre llm-coding-agent

Usage

See spec.md for the full design.

This package is an LLM plugin: installing it adds an llm code command that starts an interactive coding agent session in the current directory, using any tool-capable model LLM knows about:

llm code                                   # interactive session, default model
llm code "add type hints to utils.py"      # start with an initial task
llm code -m gpt-4.1 -d ~/dev/myproject     # pick a model and directory
llm code --yolo                            # auto-approve every tool call
llm code --allow "pytest*" --allow "git diff*"   # pre-approve some commands

The model can read, search and edit files under the session directory and run shell commands there. Read-only tools run freely; file writes, edits and shell commands show you what the model wants to do and ask for approval - y approves once, a approves similar actions for the rest of the session, anything else declines (the model is told, and can try another approach). Inside a session !quit exits, !yolo toggles auto-approval, !model MODEL switches models mid-conversation and !tokens reports token usage.

Sessions are logged to LLM's SQLite database just like llm chat, so llm logs shows full transcripts including every tool call, and conversations can be resumed:

llm code -c                 # continue the most recent conversation
llm code --cid 01ab...      # continue a specific conversation ID
llm logs --short            # review what the agent did

The plugin also registers the toolbox with LLM itself, so the same tools work with llm chat or llm prompt:

llm chat --tool CodingTools --chain-limit 20

CodingAgent

CodingAgent runs the full agent loop against any LLM model that supports tools:

from llm_coding_agent import CodingAgent

agent = CodingAgent(
    model="gpt-4.1-mini",        # any llm model ID, or a model instance
    root="/path/to/project",
    approve=True,                # approve every tool call
)
result = agent.run("Fix the failing test in tests/test_parser.py")
print(result.text)               # the model's final answer
for tool_call, tool_result in result.tool_calls:
    print(tool_call.name, tool_call.arguments)

agent.run("Now add a changelog entry")   # the conversation continues

The approve= parameter controls what happens when the model wants to run a mutating tool (write_file, edit_file, execute_command - read-only tools never ask):

  • approve=True approves everything
  • approve=callable - a (tool, tool_call) -> bool function; returning False cancels that call and the model is told it was declined
  • approve=None (the default) pauses the run: result.paused is true, result.pending_tool_calls lists what the model wants to do, and calling agent.resume() approves those calls and continues the loop - useful for approval flows in applications with no terminal attached

A chain_limit= (default 25) bounds how many tool-execution rounds a single run() can use; if it is hit, result.hit_limit is true.

CodingTools

The tools themselves live on CodingTools, an llm.Toolbox confined to a root directory, usable directly with model.chain():

from llm_coding_agent import CodingTools

tools = CodingTools("/path/to/project")
print(tools.read_file("README.md"))          # numbered lines, like cat -n
print(tools.read_file("big.log", offset=100, limit=50))
tools.write_file("notes/todo.md", "- ship it\n")   # creates parent dirs
print(tools.edit_file("app.py", "DEBUG = True", "DEBUG = False"))

edit_file performs exact string replacement: old_string must appear exactly once in the file (pass replace_all=True to replace every occurrence) and the tool returns a unified diff of the change so the model can verify what it did.

For exploring a project there are two search tools:

print(tools.list_files("**/*.py"))            # newest first, respects .gitignore
print(tools.search_files("TODO", glob="*.py"))  # path:line:content matches

search_files uses ripgrep when it is installed and falls back to a pure-Python scan (with identical output format) when it is not.

Shell commands run in the session root, with stdout and stderr interleaved and the exit code reported at the end:

print(tools.execute_command("pytest -x", timeout=300))

On timeout (default 120s, capped at 600s) the entire process tree is killed and any partial output is returned.

All file access is confined to the root directory - relative paths resolve against it, and any path that escapes it (via .., absolute paths or symlinks) returns an Error: string instead of file content, so a model using these tools can see and correct its mistake.

Development

To contribute to this library, first checkout the code. Then create a new virtual environment:

cd llm-coding-agent
python -m venv venv
source venv/bin/activate

Now install the dependencies and test dependencies:

python -m pip install -e '.[test]'

To run the tests:

python -m pytest

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

llm_coding_agent-0.1a0.tar.gz (25.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

llm_coding_agent-0.1a0-py3-none-any.whl (19.3 kB view details)

Uploaded Python 3

File details

Details for the file llm_coding_agent-0.1a0.tar.gz.

File metadata

  • Download URL: llm_coding_agent-0.1a0.tar.gz
  • Upload date:
  • Size: 25.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for llm_coding_agent-0.1a0.tar.gz
Algorithm Hash digest
SHA256 900c7001849ef1013da6dad95e2efc7405b7a0fd7a17b854b483357813b20da7
MD5 c1fa1cdd3b81de9e12884985d7f328d0
BLAKE2b-256 48c4ab5eb9eb787df526d6ba64123830aa65dbc79aa76445063d9986765d33c8

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_coding_agent-0.1a0.tar.gz:

Publisher: publish.yml on simonw/llm-coding-agent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file llm_coding_agent-0.1a0-py3-none-any.whl.

File metadata

File hashes

Hashes for llm_coding_agent-0.1a0-py3-none-any.whl
Algorithm Hash digest
SHA256 3e9ad2081d880c2fd16713548fc7fe165b8159aed621562b7e6173e56ed4ed67
MD5 5ae1c34d3b653bc8c28e2bf36c106039
BLAKE2b-256 14710229f11023fb92cd581f2778fe9ada9935cac4e37e3fedef9be2fc31bc79

See more details on using hashes here.

Provenance

The following attestation bundles were made for llm_coding_agent-0.1a0-py3-none-any.whl:

Publisher: publish.yml on simonw/llm-coding-agent

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page