Post-Edit Formatter

Automatically format files after agent edits using ruff, prettier, gofmt, or rustfmt

Run your project’s formatter after every agent file edit so style stays consistent without extra steps.

python
from praisonaiagents import Agent
from praisonaiagents.tools.edit_tools import create_edit_tools

edit_tools = create_edit_tools(post_edit_format="auto")

coder = Agent(
    name="Coder",
    instructions="Edit files cleanly and keep formatting consistent.",
    tools=edit_tools,
)
coder.start("Refactor utils.py to use list comprehensions")

The user asks for a refactor; the formatter runs automatically after each file edit.

Diagram

off

auto

🤖 Agent

edit_file

post_edit_format?

✅ Done

⚙️ Formatter

How It Works

Diagram
PostEditFormatterAgentUserPostEditFormatterAgentUserRequestProcessResultResponse

Quick Start

  1. Simple Usage

    Enable auto-formatting on edit tools:

    python
    from praisonaiagents import Agent
    from praisonaiagents.tools.edit_tools import create_edit_tools
    
    edit_tools = create_edit_tools(post_edit_format="auto")
    
    coder = Agent(
        name="Coder",
        instructions="Edit the file as requested.",
        tools=edit_tools,
    )
    coder.start("Add type hints to models.py")
  2. With Configuration

    Pin formatters per extension:

    python
    from praisonaiagents import Agent
    from praisonaiagents.tools.edit_tools import create_edit_tools
    
    edit_tools = create_edit_tools(
        post_edit_format="auto",
        formatters={
            ".py": ["ruff", "format", "{path}"],
            ".ts": ["./node_modules/.bin/prettier", "--write", "{path}"],
        },
    )
    
    coder = Agent(name="PolyglotCoder", instructions="Edit Python and TypeScript.", tools=edit_tools)

How It Works

Diagram
Post-Edit FormatterAgentUserPost-Edit FormatterAgentUserRequestProcess requestResultResponse

After a successful edit_file or apply_patch, the pipeline detects a formatter by file extension, runs it, and re-reads the file on exit code 0.

ExtensionDefault command
.pyruff format {path} (falls back to black)
.js, .ts, .tsx, .json, .css, .mdprettier --no-config --no-editorconfig --write {path}
.gogofmt -w {path}
.rsrustfmt {path}

The {path} placeholder is the absolute path to the edited file. If omitted from your argv list, it is appended automatically.

Diagnostics: unavailable note

When an edited file has a known LSP language whose server is not installed and no legacy checker is available, the edit output now appends a one-time-per-language note:

Diagnostics (lsp:<lang>): unavailable — language server `<cmd>` not found on PATH; install with `<hint>`

For example, editing a Python file with no pylsp on PATH:

Diagnostics (lsp:python): unavailable — language server `pylsp` not found on PATH; install with `pip install python-lsp-server`

This replaces the previous silent no-op — the lost self-correction signal is now visible. The note is deduplicated per language per run, so install the server once and it disappears. See LSP Auto-Detect to probe availability before you run.


Configuration Options

OptionTypeDefaultDescription
post_edit_formatstr"off""off", "auto", or "on"
formattersdict[str, list[str]]Built-in mapPer-extension formatter argv
post_edit_diagnosticsstr"auto"Separate linter/diagnostics pass

Best Practices

Start with auto mode

post_edit_format="auto" runs a formatter only when one is on PATH — zero cost when none is installed.

Use project-local prettier

Prefer ./node_modules/.bin/prettier so the version matches package.json.

Pin formatter versions in CI

Match local and CI formatter versions to avoid diff churn between runs.

Skip when CI already formats

Most useful for interactive agent sessions where you want immediate clean output.


Related