Skip to main content

Selection-based mutable output buffer for LLM tools

Project description

editbuffer

editbuffer is a small Python runtime for editing an LLM's pending text output before it is committed.

The public abstraction is selection-based editing, not file patches:

  • select exact, contextual, fuzzy, block, or character-range targets;
  • replace, insert before/after, or delete the selection;
  • reject missing, ambiguous, invalid, and stale selections;
  • inspect the current buffer and its audit history;
  • commit the final artifact.

Install

pip install editbuffer

For local development:

python -m pip install -e .

Python 3.11+ is required. The core library has no runtime dependencies.

Quickstart

from editbuffer import EditBuffer, Selection

buf = EditBuffer()
buf.append('find . -name "*.py" -exec grep -n "TODO" {} ;')
buf.replace(Selection.exact("{} ;"), "{} \\;")

final = buf.commit()

Selections can also be dictionaries:

buf.replace(
    {
        "type": "context",
        "before": 'grep -n "TODO" ',
        "text": "{} ;",
        "after": "",
    },
    "{} \\;",
)

LLM tool-call format

{
  "op": "replace",
  "target": {
    "type": "context",
    "before": "grep -n \"TODO\" ",
    "text": "{} ;",
    "after": ""
  },
  "text": "{} \\;"
}

Pass the decoded object to buffer.apply(operation). Supported operations are append, replace, insert_before, insert_after, and delete.

Range selections use half-open character offsets and can reject stale edits:

{
  "op": "delete",
  "target": {
    "type": "range",
    "start": 10,
    "end": 20,
    "expected_version": 3
  }
}

Failure behavior

  • no match raises TargetNotFoundError;
  • multiple matches raise AmbiguousTargetError with candidate ranges;
  • occurrence can explicitly choose a zero-based match;
  • invalid ranges or operations raise InvalidOperationError;
  • a mismatched expected_version raises StaleVersionError;
  • validator failures do not mutate text or history;
  • fuzzy matching is opt-in and rejects low-confidence or competing candidates.

Fuzzy and block selections

Fuzzy selection uses the standard library and records the accepted confidence:

buf.replace(
    Selection.fuzzy(
        "run integrtion tests",
        threshold=0.85,
        ambiguity_margin=0.05,
    ),
    "run unit tests",
)

It never runs as a fallback for exact/context selection. If no candidate meets the threshold, or two candidates are too close, FuzzyMatchError includes candidate ranges and scores.

Block selection requires an explicit ID. Fenced code blocks use:

```python editbuffer:id=setup
print("old")
```

Markdown regions use:

<!-- editbuffer:block summary -->
old content
<!-- /editbuffer:block -->

Selection.block("setup") selects the content inside the markers, preserving the fence or comments. Duplicate IDs are rejected as ambiguous.

Snapshots and rollback

Every successful edit stores an in-memory snapshot:

buf.append("draft")
version = buf.version
buf.replace(Selection.exact("draft"), "final")
buf.rollback(version)

Rollback restores the snapshot as a new audited version. Snapshots live only for the lifetime of the EditBuffer process.

Optional validators

from editbuffer import EditBuffer
from editbuffer.validators import valid_json, valid_shell

json_buffer = EditBuffer('{"ok": true}', validators=(valid_json,))
shell_buffer = EditBuffer("echo ok", validators=(valid_shell,))

valid_shell invokes the local POSIX sh -n parser without executing the command.

CLI

The CLI stores an operation log in a JSON state file:

editbuffer new /tmp/output.json --text "hello world"
editbuffer replace /tmp/output.json '{"type":"exact","text":"world"}' "there"
editbuffer view /tmp/output.json
editbuffer history /tmp/output.json
editbuffer rollback /tmp/output.json 1
editbuffer commit /tmp/output.json

Use editbuffer apply STATE OPERATION_JSON for the complete operation schema.

MCP / agent integration

Install the optional server:

pipx install 'editbuffer[mcp]'

Or install with uvx without a persistent environment:

uvx --from 'editbuffer[mcp]' editbuffer-mcp

Connect it to Codex:

codex mcp add editbuffer -- editbuffer-mcp

Codex supports local STDIO MCP servers configured with codex mcp add; use /mcp in the Codex terminal UI to confirm the server is active.

Claude Desktop and generic MCP client examples are in docs/mcp.md.

The server exposes:

  • buffer_append
  • buffer_list
  • buffer_view
  • buffer_edit
  • buffer_replace
  • buffer_insert_before
  • buffer_insert_after
  • buffer_delete
  • buffer_history
  • buffer_rollback
  • buffer_commit
  • tool_history
  • tool_select

Buffers are in-memory and live for the MCP server process. The MCP layer calls the same core API and does not implement separate edit semantics.

Use the first-class selection tools for normal agent use:

{
  "buffer_id": "answer",
  "target": {"type": "exact", "text": "old"},
  "text": "new"
}

buffer_edit remains available for raw JSON operations.

MCP calls are recorded in SQLite-backed history. tool_history returns recent calls, newest first. tool_select creates a pending buffer from selectable content in a previous call so the model can repair it instead of regenerating it.

Examples

Scope

This project is not:

  • an agent framework;
  • a retrieval system or repo indexer;
  • a full IDE;
  • a replacement for coding agents;
  • a generic output quality evaluator.

Persistent storage, atomic operation batches, TypeScript bindings, and syntax-aware block parsing are future work.

Development

PYTHONPATH=src python -m unittest discover -s tests -v

License

MIT

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

editbuffer-0.2.3.tar.gz (26.1 kB view details)

Uploaded Source

Built Distribution

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

editbuffer-0.2.3-py3-none-any.whl (19.3 kB view details)

Uploaded Python 3

File details

Details for the file editbuffer-0.2.3.tar.gz.

File metadata

  • Download URL: editbuffer-0.2.3.tar.gz
  • Upload date:
  • Size: 26.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for editbuffer-0.2.3.tar.gz
Algorithm Hash digest
SHA256 c0f250f4adbd3efab26c6eaf282f8419583476eba6a9e798277485c3b492dbcf
MD5 3232ad682d72db85188d2c62b9eb92af
BLAKE2b-256 396fad8de482ea64f6517cdc0febde0a8e5bfc304981e3e0b183cda6b6096a7e

See more details on using hashes here.

File details

Details for the file editbuffer-0.2.3-py3-none-any.whl.

File metadata

  • Download URL: editbuffer-0.2.3-py3-none-any.whl
  • Upload date:
  • Size: 19.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for editbuffer-0.2.3-py3-none-any.whl
Algorithm Hash digest
SHA256 314a351d5d608a947281f11370946108029de5042194791b73762726cb05ef5f
MD5 c412338bf659e6f0b121f4ffefeaab29
BLAKE2b-256 edda4554cabc6a1b9322d42d6662a37a9f47ceb22ad11a285a83043c3cfee114

See more details on using hashes here.

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