Skip to main content
CodePilot logo

Embeddable Autonomous Agent Runtime for Software Engineering

PyPI version Python License Docs

Embeddable Autonomous Agent (EAA)Code-as-Interface RuntimeTerminal MultiplexerMIT Licensed

pip install codepilot-ai

What CodePilot Is

CodePilot is a Python library for embedding autonomous software-engineering agents into your own products: CLIs, FastAPI services, hosted code-server workspaces, internal developer tools, CI repair systems, and local automation.

It is intentionally not a hosted chatbot UI. The package gives applications a runtime: model inference, tool execution, file editing, terminal control, persistence, hooks, and completion semantics. You bring the product surface, auth model, sandbox, database, and deployment strategy.

Version: 0.9.21

Full user documentation lives at: https://Jahanzeb-git.github.io/codepilot/

Quick Start

Create an agent.yaml:

agent:
  name: CodePilot
  role: Autonomous software engineering agent.

  model:
    provider: anthropic
    name: claude-sonnet-4-5
    api_key_env: ANTHROPIC_API_KEY

  runtime:
    work_dir: ./workspace
    max_steps: 20
    unsafe_mode: false

  tools:
    - name: read_file
      enabled: true
    - name: execute
      enabled: true
      config:
        require_permission: true
    - name: read_output
      enabled: true
    - name: send_input
      enabled: true
    - name: terminate_terminal
      enabled: true
    - name: find
      enabled: true

Gemini can be configured with a Gemini API key from Google AI Studio:

agent:
  model:
    provider: gemini
    name: gemini-3.5-flash
    api_key_env: GEMINI_API_KEY

Run the agent:

from codepilot import Runtime, on_stream, on_finish

runtime = Runtime("agent.yaml", stream=True)

@on_stream(runtime)
def stream(text: str, **_):
    print(text, end="", flush=True)

@on_finish(runtime)
def finish(summary: str, **_):
    print(f"\nDone: {summary}\n")

summary = runtime.run("Inspect the project and fix the failing tests.")
print(summary)

Async applications should use AsyncRuntime:

from codepilot import AsyncRuntime

runtime = AsyncRuntime("agent.yaml", session="db", db=async_engine, stream=True)
summary = await runtime.run("Refactor the repository layer to use async SQLAlchemy.")

Architecture

CodePilot is designed as a library-first runtime that can be embedded under many product surfaces.

flowchart TD
    A[Your app: CLI, FastAPI, code-server extension, desktop app] --> B[CodePilot Runtime]
    B --> C[LLM Provider]
    B --> D[Tool Registry]
    D --> E[Filesystem Tools]
    D --> F[Terminal Tools]
    D --> G[Search and Context Tools]
    B --> H[Session Backend]
    H --> I[Memory]
    H --> J[File JSON]
    H --> K[SQLAlchemy Database]
    F --> L[PTY / ConPTY]
    L --> M[Unix Socket Multiplexer on POSIX]

For hosted web IDE deployments, the intended shape is a small control plane plus disposable per-user runtime machines:

flowchart LR
    Browser --> FlyProxy["Fly Proxy"]
    FlyProxy --> CodeServer["code-server :8080"]
    CodeServer --> Extension["Custom code-server extension"]
    Extension --> RuntimeSock["/run/codepilot/runtime.sock"]
    RuntimeSock --> Daemon["CodePilot runtime daemon"]
    Daemon --> TerminalSock["/tmp/codepilot_main.sock"]
    Daemon --> Postgres[("Postgres / Neon")]
    Daemon --> ObjectStore[("Backblaze B2 snapshots")]
    Daemon --> Workspace["Workspace files"]

Why Code-as-Interface

Most agent frameworks force the model to express actions as JSON function calls. CodePilot uses a diff-native Code-as-Interface protocol: each workspace mutation is a self-contained unified diff, and tool calls live in a fresh ephemeral codepilot.py diff:

I will inspect the failing test first.

```diff
diff --git a/codepilot.py b/codepilot.py
--- /dev/null
+++ b/codepilot.py
@@ -0,0 +1,2 @@
+view_file("tests/test_api.py")
+execute("main", "pytest tests/test_api.py -q", timeout=30)
```

The runtime executes only the generated ephemeral codepilot.py script. Ordinary Python markdown remains display text and is never executed.

This design is useful because software work is naturally procedural:

  • Agents often need several tool calls in a deliberate order.
  • Tool results need to feed control flow inside the same step.
  • File writes use reviewable, self-describing diffs instead of fragile escaped strings or positional payloads.
  • Developers need observable execution results, not opaque function-call envelopes.

The model still operates under a strict protocol:

  • diff --git a/path b/path: a complete file mutation.
  • diff --git a/codepilot.py b/codepilot.py: fresh executable tool script.
  • task(finish=True) in the script: explicit task-finished signal.

This aligns with research showing that LLM agents benefit from interleaving reasoning and environment actions, as in ReAct, and from well-designed agent-computer interfaces for software engineering tasks.

How File Editing Works

Each hunk is applied by reconstructing its old and new blocks. The runtime ignores @@ line counts, uniquely finds the old block in the current file while ignoring indentation, then replaces it with the new block. Context lines retain the file's actual indentation. A zero-match or multi-match hunk is rejected without guessing.

diff --git a/config.py b/config.py
--- a/config.py
+++ b/config.py
@@ -999,1 +999,1 @@
-TIMEOUT = 30
+TIMEOUT = 60

For creation or a complete rewrite, emit a pure-addition hunk. If an OS-level failure occurs after a large diff is parsed, CodePilot reports diff_cache_id; repair the condition in codepilot.py and call retry_diff(id) to replay the exact cached operation.

Safety properties:

  • Paths are constrained to runtime.work_dir unless unsafe_mode: true.
  • Edits use unique content matching before mutation; hunk counts are never trusted.
  • Multiple hunks are applied against evolving in-memory content, then committed atomically per file diff.
  • Tool results are appended back into the conversation as ground truth.

How Terminal Tools Work

CodePilot starts a default terminal session named main when the runtime is created. The session persists across run() calls.

execute("main", "pytest tests/ -v", timeout=30)

Long-running commands return with status: running instead of hanging the agent:

execute("server", "uvicorn app.main:app --port 8000", timeout=4, new_terminal=True)
read_output("server", timeout=10)
execute("main", "pytest tests/test_api.py -v", timeout=30)
send_input("server", "\x03", timeout=5)

Terminal architecture:

  • Linux/macOS use pexpect and a PTY.
  • Windows 10 1809+ uses ConPTY through pywinpty.
  • POSIX terminal sessions are exposed through a Unix socket multiplexer.
  • Multiple clients can attach to the same terminal stream, enabling a code-server extension or xterm.js bridge to share the shell with the agent.
flowchart TD
    Bash[bash process] <--> PTY[PTY master]
    PTY <--> Mux[MuxServer]
    Mux <--> AgentClient[CodePilot terminal tool client]
    Mux <--> UIClient[code-server / xterm.js client]

Persistence Model

Session backends are selected at runtime construction:

Runtime("agent.yaml")                                      # memory
Runtime("agent.yaml", session="file", session_id="demo")   # JSON file
Runtime("agent.yaml", session="db", db_url="sqlite:///./codepilot.db")

For async web apps, pass the engine your application owns:

from sqlalchemy.ext.asyncio import create_async_engine
from codepilot import AsyncRuntime

engine = create_async_engine(
    DATABASE_URL,
    pool_size=5,
    max_overflow=10,
    pool_pre_ping=True,
)

runtime = AsyncRuntime("agent.yaml", session="db", db=engine)

Important deployment rule:

A SQLAlchemy engine is a local process object, not the database. Different processes or MicroVMs should create their own engine or receive their own engine from the application process, even if all engines point to the same Postgres database.

Observability and Product Integration

Hooks are the UI and orchestration contract:

from codepilot import EventType

runtime.hooks.register(
    EventType.STREAM,
    lambda text, **_: send_to_ui({"type": "stream", "text": text}),
)

runtime.hooks.register(
    EventType.TOOL_CALL,
    lambda tool, args, label="", **_: send_to_ui({
        "type": "tool_call",
        "tool": tool,
        "label": label,
        "args": args,
    }),
)

runtime.hooks.register(
    EventType.TOOL_RESULT,
    lambda tool, result, **_: send_to_ui({
        "type": "tool_result",
        "tool": tool,
        "result": result,
    }),
)

This allows applications to stream progress, render tool timelines, request approvals, inject mid-task messages, and persist final summaries without coupling the UI to runtime internals.

Security Model

CodePilot gives agents real software-engineering capabilities. The runtime is not a security sandbox by itself.

Recommended production posture:

  • Run untrusted workspaces inside containers, MicroVMs, or OS sandboxes.
  • Use unsafe_mode: false by default.
  • Gate shell execution with require_permission: true.
  • Use short-lived machine/session tokens in hosted workspaces.
  • Keep user auth, runtime auth, and database credentials separate.
  • Prefer disposable machines plus Postgres/object-storage persistence for hosted demos.

Research Grounding

CodePilot’s design is influenced by agent and tool-use research:

CodePilot translates those ideas into a small Python library focused on practical software work: ephemeral executable scripts, content-addressed diff edits, persistent terminals, observable hooks, and pluggable session storage.

Documentation

The README is intentionally architectural. Use the documentation site for library usage:

  • Installation and AgentFile configuration
  • Runtime and streaming behavior
  • File, terminal, search, and context tools
  • Session persistence
  • Hooks and permission gating
  • FastAPI and hosted workspace patterns
  • API reference

Docs: https://Jahanzeb-git.github.io/codepilot/

License

MIT License. See LICENSE.

Download files

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

Source Distribution

codepilot_ai-0.9.27.tar.gz (142.9 kB view details)

Uploaded Source

Built Distribution

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

codepilot_ai-0.9.27-py3-none-any.whl (152.3 kB view details)

Uploaded Python 3

File details

Details for the file codepilot_ai-0.9.27.tar.gz.

File metadata

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

File hashes

Hashes for codepilot_ai-0.9.27.tar.gz
Algorithm Hash digest
SHA256 8eef0eaf3fb2d19b2d8147278b48cc836d34a4cf9a2e84be5c55b5dd732e83cf
MD5 ab8f29981a5d0b99dd8057f71543a767
BLAKE2b-256 13d61311f8984f35176ae6c43380ccf0de34bb558fa0d9bf0311380676cbd006

See more details on using hashes here.

Provenance

The following attestation bundles were made for codepilot_ai-0.9.27.tar.gz:

Publisher: publish.yml on Jahanzeb-git/codepilot

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

File details

Details for the file codepilot_ai-0.9.27-py3-none-any.whl.

File metadata

  • Download URL: codepilot_ai-0.9.27-py3-none-any.whl
  • Upload date:
  • Size: 152.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for codepilot_ai-0.9.27-py3-none-any.whl
Algorithm Hash digest
SHA256 72100cce1f7f7d57678eca1cc87b7950991a709e3691edd784a1897d0569cd8e
MD5 e992801dc52087f231b079d583698aea
BLAKE2b-256 eb29884f5054ba543a27bae52c7f2b4f393480879a8c7c755b367d1fe666f92a

See more details on using hashes here.

Provenance

The following attestation bundles were made for codepilot_ai-0.9.27-py3-none-any.whl:

Publisher: publish.yml on Jahanzeb-git/codepilot

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

Release history Release notifications | RSS feed

0.9.31

2 files

0.9.30

2 files

0.9.29

2 files

0.9.28

2 files

This release

0.9.27 This release

2 files

0.9.26

2 files

0.9.25

2 files

0.9.24

2 files

0.9.23

2 files

0.9.22

2 files

0.9.21

2 files

0.9.20

2 files

0.9.19

2 files

0.9.18

2 files

0.9.17

2 files

0.9.15

2 files

0.9.13

2 files

0.9.12

2 files

0.9.11

2 files

0.9.10

2 files

0.9.9

2 files

0.9.8

2 files

0.9.7

2 files

0.9.6

2 files

0.9.5

2 files

0.9.4

2 files

0.9.3

2 files

0.9.2

2 files

0.9.1

2 files

0.9.0

2 files

0.8.8

2 files

0.8.7

2 files

0.8.6

2 files

0.8.5

2 files

0.8.4

2 files

0.8.3

2 files

0.8.2

2 files

0.8.1

2 files

0.8.0

2 files

0.7.0

2 files

0.6.1

2 files

0.6.0

2 files

0.5.1

2 files

0.5.0

2 files

0.4.0

2 files

0.3.2

2 files

0.3.1

2 files

0.3.0

2 files

0.2.2

2 files

0.2.1

2 files

0.2.0

2 files

Supported by

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