Skip to main content

python-agent-harness

A lightweight Python coding-agent harness for reliable autonomous coding.
FSM-driven execution · OpenAI-compatible · built for daily use and easy customization

CI Python License: MIT

A terminal coding agent that reads your codebase, plans changes, edits files, runs commands, and verifies its work.

python-agent-harness is inspired by gptel-agent-harness and opencode. It brings opencode's prompts and core behaviors—such as AGENTS.md discovery, plan/build modes, skills, sub-agents, and todo tracking—into a lightweight Python implementation with only three runtime dependencies:

  • rich
  • httpx
  • prompt_toolkit

It works with any OpenAI-compatible API and is designed to be easy to inspect, customize, and use for everyday software development.

Demo

python-agent-harness demo

Quick start

Install from PyPI

pip install python-agent-harness

python-agent-harness config --init
python-agent-harness run

Optional extras:

pip install "python-agent-harness[mcp]"   # MCP server integration
pip install "python-agent-harness[dev]"   # development tools

Install from source (GitHub)

git clone git@github.com:beacoder/python-agent-harness.git
cd python-agent-harness

make install
. venv/bin/activate

python-agent-harness config --init
python-agent-harness run

Optional extras:

pip install -e ".[mcp]"   # MCP server integration
pip install -e ".[dev]"   # development tools

Edit ~/.config/python-agent-harness/config.json and set your base_url, api_key, and model.

Features

  • FSM-driven execution — explicit WAIT / TOOL / TRET / SUPERVISE / DONE / ERRS / ABRT states. Completion supervision nudges the model when it stops early, while failed tool calls are sanitized so they never strand the agent. Transient API failures (429 / 5xx) retry with exponential backoff and jitter.
  • Context management — CJK-aware token estimation, per-model context windows, and automatic compaction at 70% usage.
  • Coding toolsAgent, TodoWrite, Glob, Grep, Read, Insert, Edit (including unified diffs), Write, Mkdir, Bash, Skill, Question, and PlanExit. Synchronous tools execute sequentially; asynchronous tools such as Bash and Agent can run concurrently while preserving emitted order.
  • Plan / Build modes — plan mode is read-only except for the per-session plan file.
  • Persistent sessions — sessions are automatically saved after every response to ~/.local/share/python-agent-harness/sessions/, with LLM-generated titles and support for /restore --latest and /sessions.
  • Focused TUI — a Rich-based interface with a pinned status bar, Todos panel, inline red/green diff rendering for Edit and Write, and a prompt_toolkit editor with history and completion. Esc+Enter submits, Ctrl-D quits, and Ctrl-C cancels without leaving the application.
  • MCP support — optional MCP integration through the [mcp] extra. MCP tools become ordinary agent tools such as mcp__<server>__<tool>. Supports stdio, streamable-http, and sse transports.
  • Slash commands — built-in /init, /review, /explain, and other commands, plus custom commands loaded from prompts/commands/*.md.

Inspired by opencode

Most of opencode's prompts and core behaviors have been ported to this project. The goal is to retain its practical coding-agent workflow while keeping the implementation small, dependency-light, and easy to customize.

Prompt and behavior mapping

The following opencode prompts have corresponding implementations in python-agent-harness:

opencode python-agent-harness
default.txt (main agent) agent.md
plan.txt / plan-mode.txt / build-switch.txt plan.md / plan-mode.md / build-switch.md
task.txt (sub-agent) subagent.md + Agent tool
todowrite.txt / question.txt / skill.txt TodoWrite / Question / Skill tools
read.txt / write.txt / edit.txt / grep.txt / glob.txt Read / Write / Edit / Grep / Glob tools
shell.txt Bash tool + agent.md Git/GitHub guidance
plan-enter.txt / plan-exit.txt PlanExit tool
initialize.txt / review.txt / explain initialize.md / review.md / commands/explain.md
compaction / summary / title compact.md / summary.md / title.md
AGENTS.md handling prompts.py (find_agents_md_files, load_context_files, per-file resolution)

Configuration

All LLM settings live in a single JSON configuration file. Environment variables are optional.

{
  "llm": {
    "base_url": "https://api.openai.com/v1",
    "api_key": "sk-...",
    "model": "gpt-5-mini",
    "reasoning_effort": null,
    "stream": true
  },
  "models": {
    "_comment": "Named LLM profiles for /model switching. Partial settings; unset keys inherit the main llm.",
    "deepseek": {
      "base_url": "https://api.deepseek.com/v1",
      "model": "deepseek-chat"
    },
    "qwen": {
      "base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
      "model": "qwen3.5-coder"
    }
  },
  "subagent_llm": {
    "profile": null,
    "base_url": null,
    "api_key": null,
    "model": null,
    "temperature": null,
    "max_tokens": null,
    "timeout": null,
    "reasoning_effort": null,
    "stream": null
  },
  "paths": {
    "context_path": null,
    "skill_path": null
  },
  "mcp": {
    "servers": {
      "example": {
        "transport": "stdio",
        "command": "npx",
        "args": [
          "-y",
          "@modelcontextprotocol/server-filesystem",
          "/tmp"
        ],
        "env": [],
        "parallel": false,
        "timeout": null,
        "enabled": false
      }
    }
  }
}

Configuration options

  • llm — main LLM configuration. Optional keys include backend, temperature, max_tokens, timeout, reasoning_effort, and stream. Values such as reasoning_effort are passed to the API as-is when set. run --no-stream overrides stream.
  • models — named LLM profiles for runtime switching with /model. A profile is a partial settings dictionary; unset keys inherit from the main llm. default restores the main LLM configuration.
  • subagent_llm — LLM configuration for Agent tool requests. Unset values inherit from the main llm. Set profile to reuse a profile from models. Precedence is: profile settings > explicit subagent_llm settings > main llm > environment variables.
  • paths.context_path / paths.skill_path — locations from which to load context files and skills. When unset, the project-local <project>/contexts and <project>/skills directories are used.
  • mcp.servers — MCP server configuration. Requires the [mcp] extra. Each server supports transport, command, args, env, url, headers, parallel, timeout, and enabled.
  • Configuration precedence — code defaults < config file < OPENAI_* environment variables. Sub-agent settings also support OPENAI_SUBAGENT_* (_BASE_URL, _API_KEY, _MODEL, _BACKEND).
  • Custom config — use --config PATH or PYTHON_AGENT_HARNESS_CONFIG.
  • LLM logging — request and response bodies are logged as JSON to /tmp/python-agent-harness-<date>-<id>.json. Set LLM_LOG_DIR to change the directory. The log path is printed at startup.

Usage

python-agent-harness run [project-dir]

Launches the interactive TUI agent. If project-dir is omitted, the current directory is used.

Slash commands

Command Description
/plan / /build Switch between read-only plan mode and build mode
/init Create or update AGENTS.md
/review Review uncommitted changes, commits, branches, or pull requests
/explain [project] [target] Explain code
/compact Compact the conversation
/summary Append a conversation summary
/save Save the current session
/sessions List saved sessions
/restore [path|title|--latest|latest] Restore a session; title matching uses substring search
/clear Start a fresh conversation
/model [name] Switch LLM profiles; default restores the session's original model
/exit Quit

Custom commands from prompts/commands/*.md are registered as slash commands as well (TUI only).

Project layout

python_agent_harness/
├── agent.py           # Agent FSM core: states, transitions, supervision
├── tool_runner.py     # Tool-call execution/delivery + history salvage
├── context_manager.py # Context-ratio tracking + compaction
├── client.py          # OpenAI-compatible streaming client (httpx)
├── models.py          # Message / ToolCall / ToolSpec data classes
├── token_estimator.py # CJK-aware token estimation + calibration
├── planmode.py        # Plan/build modes + plan-file lifecycle
├── prompts.py         # Prompt loading + system-prompt assembly
├── persistence.py     # Session persistence + titles
├── session.py         # Session wiring hub + MCP lifecycle
├── subagent.py        # Sub-agent runner + error containment
├── commands.py        # Init/review/custom command definitions
├── cli.py             # CLI entry points
├── tui/               # Rich + prompt_toolkit TUI (package)
├── diffrender.py      # Unified diff generation + Rich rendering
├── mcp/               # Optional MCP client
└── tools/             # Tool implementations + registry

Development

Requires Python ≥ 3.11. CI runs against Python 3.11, 3.12, and 3.13.

make test                           # unit tests
venv/bin/pip install -e ".[dev]"    # development tools
venv/bin/ruff check .               # lint
venv/bin/pyright                    # type checking
venv/bin/python -m build            # build sdist + wheel
venv/bin/pip-audit                  # dependency audit

CI blocks on Ruff and Pyright failures.

Design philosophy

Keep it intact, not bloated.

The project aims to provide a capable coding-agent within a lightweight framework.

Related projects

  • gptel-agent-harness — the Emacs-based implementation that inspired this project.
  • opencode — the primary source of many prompts and coding-agent behaviors.

License

MIT

Download files

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

Source Distribution

python_agent_harness-1.5.2.tar.gz (230.9 kB view details)

Uploaded Source

Built Distribution

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

python_agent_harness-1.5.2-py3-none-any.whl (162.2 kB view details)

Uploaded Python 3

File details

Details for the file python_agent_harness-1.5.2.tar.gz.

File metadata

  • Download URL: python_agent_harness-1.5.2.tar.gz
  • Upload date:
  • Size: 230.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for python_agent_harness-1.5.2.tar.gz
Algorithm Hash digest
SHA256 b021529ba20a0afc52f5d69f1bcbd21614a2d54f5f65b136fc293d0d7fdc3c9f
MD5 ca6791b4a8f75d310acbf089bcce2c9c
BLAKE2b-256 e2f2b7c49a3ea18f9f7d47cc3fe92df0ca9151bbdbfd39f53012c0b12496063a

See more details on using hashes here.

Provenance

The following attestation bundles were made for python_agent_harness-1.5.2.tar.gz:

Publisher: release.yml on beacoder/python-agent-harness

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

File details

Details for the file python_agent_harness-1.5.2-py3-none-any.whl.

File metadata

File hashes

Hashes for python_agent_harness-1.5.2-py3-none-any.whl
Algorithm Hash digest
SHA256 adce7728406ece87f283958e8dc60a5ebed1b3714b155d67bf53da63336ea4fd
MD5 9ff8c5132d01dc8bc3eab04e495be9ea
BLAKE2b-256 f7c068a3e77baac279f71073baab24745be0bafcdc7874adb71a170d970a298b

See more details on using hashes here.

Provenance

The following attestation bundles were made for python_agent_harness-1.5.2-py3-none-any.whl:

Publisher: release.yml on beacoder/python-agent-harness

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

Release history Release notifications | RSS feed

1.5.3

2 files

This release

1.5.2 This release

2 files

1.5.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page