A Pi coding-agent extension that adds an apply_patch tool and a V4A patch harness so GPT-5.2 / GPT-5.2-Codex can propose structured diffs which Pi applies.
This follows the OpenAI Apply Patch / V4A diff flow:
- The model calls
apply_patchwith a list of operations - Each operation is one of:
create_file,update_file,delete_file - The diff format is V4A (context/add/delete lines)
- A Pi tool named
apply_patch - Path validation (prevents directory traversal)
- Atomic writes
- Streaming progress updates in the Pi TUI
mkdir -p ~/.pi/agent/extensions
cp ./codex-apply-patch.ts ~/.pi/agent/extensions/codex-apply-patch.tsThen start Pi normally.
pi -e /absolute/path/to/codex-apply-patch.tsWhen the active model is gpt-5.2 or gpt-5.2-codex, the extension:
- enables the
apply_patchtool - disables Pi's built-in
edit/writetools (so the model must use structured patches)
apply_patch expects:
{
"operations": [
{ "type": "create_file", "path": "...", "diff": "..." },
{ "type": "update_file", "path": "...", "diff": "..." },
{ "type": "delete_file", "path": "..." }
]
}Notes:
create_file.diff: full file content in V4A create mode (each line starts with+)update_file.diff: V4A diff using@@sections and+/-/linesdelete_file: nodiff
These are notes from local A/B runs to understand how “forced apply_patch” behaves vs Pi’s normal edit/write flow.
- baseline = Pi built-in
edit/write - apply_patch = this extension (forces structured diffs)
- Each number below is the mean of 10 runs on the same repo snapshot and prompt.
- Cost is taken from Pi’s JSONL
usage.cost.total.
In a tiny one-file fix, forcing apply_patch was usually slower and more expensive.
gpt-5.2: baseline $0.0467 / 44.6s vs apply_patch $0.0587 / 50.1sgpt-5.2-codex: baseline $0.0291 / 22.6s vs apply_patch $0.0405 / 33.1s
In a multi-file fix (3–5 files), results depended on the model:
gpt-5.2: baseline $0.1557 / 136.4s vs apply_patch $0.1470 / 129.7sgpt-5.2-codex: baseline $0.1002 / 82.6s vs apply_patch $0.1180 / 95.0s
Tool reliability note (10-run totals): on gpt-5.2-codex, forcing apply_patch reduced tool errors (34 → 17), but it cost more and took longer.
- apply_patch gives a nice audit trail (explicit file ops + diffs). That’s the main “quality” win.
- It doesn’t automatically guarantee cleaner code. In a few runs, models used shortcuts to get tests green (e.g. adding a hidden field like
__timesLeftor escaping types withany). - Some runs also touched unrelated files (import specifier changes, etc.). That’s not always wrong, but it adds churn.
Practical takeaway: if your priority is reviewability/reproducibility, forcing apply_patch is a good default. If you optimize for tiny one-line fixes, baseline tooling is often cheaper.
This is a single-file extension. You typically don't need to build anything; Pi loads the TypeScript directly.
- OpenAI Platform docs (Apply Patch tool): https://platform.openai.com/docs/guides/apply_patch
- OpenAI Agents SDK (TypeScript)
applyDiffreference implementation: https://github.com/openai/openai-agents-js/blob/main/packages/agents-core/src/utils/applyDiff.ts - OpenAI Agents SDK (Python)
apply_diffreference implementation: https://github.com/openai/openai-agents-python/blob/main/src/agents/apply_diff.py - OpenAI Agents SDK examples:
- TypeScript apply patch tool example: https://github.com/openai/openai-agents-js/blob/main/examples/tools/applyPatch.ts
- Python apply patch tool example: https://github.com/openai/openai-agents-python/blob/main/examples/tools/apply_patch.py
- Pi coding-agent extensions docs: https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/docs/extensions.md
MIT