@kennyfrc/pi-str-replace-editor

Model-facing str_replace_editor (view/create/str_replace/insert) for DeepSeek-family models on Pi; replaces read/edit/write for those models

Packages

Package details

extension

Install @kennyfrc/pi-str-replace-editor from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@kennyfrc/pi-str-replace-editor
Package
@kennyfrc/pi-str-replace-editor
Version
0.1.1
Published
Aug 16, 2026
Downloads
363/mo · 6/wk
Author
kennyfrc
License
unknown
Types
extension
Size
106.2 KB
Dependencies
1 dependency · 3 peers
Pi manifest JSON
{
  "extensions": [
    "./src/index.ts"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-str-replace-editor

Model-facing str_replace_editor (view / create / str_replace / insert) for Pi, enabled only for DeepSeek-family models, where it replaces the built-in read, edit, and write tools.

Why

DeepSeek-family models are tuned on the canonical Claude Code str_replace_editor surface (cat -n views, unique literal old_str, insert-after-line). Serving them pi's edit/write JSON contract wastes tokens and turns. This extension gives DeepSeek models the tool they were trained for and removes the three built-in tools that become redundant (view covers read, create covers write, str_replace/insert cover edit). bash, grep, find, ls stay active.

Semantics are a faithful port of the reference RL harness's str_replace_editor tool; its benchmark suite (tools.spec.ts) is re-characterized in test/engine.test.ts.

Gating

  • A model is "deepseek" when its id, provider, or display name matches /deepseek/i (case-insensitive, router-robust).
  • session_start + model_select swap the active tool set:
    • deepseek: read/edit/write removed, str_replace_editor added, and grep/find/ls removed by default — leaving bash + str_replace_editor, the harness minimal-preset shape those models were tuned on. Search goes through bash grep -rn/find/ls or str_replace_editor view on a directory.
    • everyone else: str_replace_editor removed, read/edit/write and grep/find/ls restored. GPT-family models keep edit/write exactly as-is (pi-apply-patch owns them there), so the two extensions never fight.
  • Defense in depth: tool_call blocks a deepseek model that somehow calls read/edit/write (pointer at str_replace_editor) and any other model that calls str_replace_editor (pointer at read/edit/write). No ordering race between extensions can produce a wrong write.

Config file ~/.pi/agent/pi-str-replace-editor.json (optional):

{
  "mode": "auto",
  "deepseekPatterns": ["deepseek"],
  "extraDisabledTools": ["grep", "find", "ls"]
}
  • mode: auto (default) | on (editor for every model) | off.
  • deepseekPatterns: regex list tested against id/provider/name.
  • extraDisabledTools: additional tool names hidden for deepseek models (default ["grep", "find", "ls"]; set to [] to keep those three).

Improvements over the harness

  • Syntax highlighting in the TUI for view results (pi's highlighter), plus a display diff for str_replace results.
  • Better errors / fallbacks:
    • old_str not found → closest lines with their line numbers + CRLF hint.
    • relative paths → the cwd-resolved absolute suggestion (Maybe you meant /abs/path?).
    • missing parent directory → mkdir -p hint; vanished files → FS_NOT_FOUND.
    • binary files → refused with a bash/xxd fallback hint.
    • view on an image returns the image as an attachment.
    • prepareArguments accepts legacy shapes (unadvertised): file_path, file:// prefixes, backtick-wrapped paths, replace_all: true.
  • Concurrency: every mutation runs inside pi's withFileMutationQueue, so parallel tool calls on the same file serialize instead of losing updates.
  • Error codes (FS_NOT_FOUND, FS_EDIT_NOT_FOUND, FS_AMBIGUOUS_EDIT, …) mirror the harness vocabulary.

Development

npm run check:str-replace-editor   # typecheck
npm run test:str-replace-editor    # benchmark port + adversarial battery