pi-m3fix

Pi extension that repairs flattened reasoning blocks in compacted sessions

Packages

Package details

extension

Install pi-m3fix from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:pi-m3fix
Package
pi-m3fix
Version
0.5.0
Published
Jul 16, 2026
Downloads
777/mo · 41/wk
Author
hypernewbie
License
MIT
Types
extension
Size
24.2 KB
Dependencies
0 dependencies · 2 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-m3fix

CI npm

Pi extension for repairing session files affected by flattened reasoning blocks.

"M3" in this name/doc refers to whatever model is currently exhibiting this behavior in your session — not a hardcoded requirement. The tool has zero dependency on any specific provider or model name. With no explicit target, /m3fix resolves to ctx.model (Pi's currently selected model), whatever that is: a built-in provider, or a fully custom one you registered yourself under any name, doesn't matter. Whatever is currently selected becomes the target that the whole session gets synced to. --provider/--api/--model override it explicitly if you need to target something other than the current model.

Install

From npm (recommended, versioned):

pi install npm:pi-m3fix

Pin to a specific version:

pi install npm:pi-m3fix@0.5.0

From GitHub, latest main:

pi install git:github.com/hypernewbie/pi-m3fix

From GitHub, pinned to a released tag:

pi install git:github.com/hypernewbie/pi-m3fix@v0.5.0

v0.1.0 was broken (see CHANGELOG.md) and has been removed. Do not install it.

Local development checkout:

pi install /path/to/pi-m3fix

Restart Pi or run /reload, then use /m3fix.

Usage

/m3fix [partial-session-id|session-file] [options]

Examples:

/m3fix --dry-run
/m3fix --force-live
/m3fix 019f311c --provider m3 --api anthropic-messages --model MiniMax-M3
/m3fix /absolute/path/to/session.jsonl --dry-run

Options:

  • --dry-run, -n — show changes without writing.
  • --force-live — repair the loaded session and reload it from disk.
  • --provider <id> — override the target provider.
  • --api <api> — override the target API.
  • --model <id> — override the target model.
  • --no-relabel — skip provider/API/model relabeling.
  • --no-unflatten — skip text-to-thinking repair.
  • --allow-empty-signature — deprecated no-op (kept for backward compatibility). The repair now always runs for anthropic-messages models regardless of registry metadata.

Behavior

For assistant messages, /m3fix can:

  1. Set provider, api, and model to the selected target model.
  2. Clear stale thinkingSignature values — but only on messages actually being relabeled away from a different provider. A signature on a message that already belongs to the target provider is left completely untouched.
  3. Neutralize foreign redacted thinking blocks — same rule: only when the message is being relabeled away from a different provider.
  4. Convert leaked-reasoning text blocks back into thinking blocks.

All four operations work for any API (anthropic-messages, openai-completions, openai-responses, etc.) — there is no API allowlist. M3 can be proxied through any of them, and none of these repairs are Anthropic-specific: thinkingSignature is a generic Pi concept (for OpenAI Responses it holds a JSON-encoded reasoning-item id, not a signature), and the leak-pattern match is pure text matching.

Leaked-reasoning detection uses pattern matching: a text block is only converted to thinking if it consists entirely of **bold phrase** segments with no prose content. This matches M3's flattened reasoning output ("**Checking license metadata**", "**Planning X**\n\n**Doing Y**") while preserving real responses that happen to start with bold ("**Vibe: hard.** This is not a shallow port..." → kept as text). Use --no-unflatten to skip this step.

Unflatten applies to all assistant turns except the last active one. Pre-compaction turns are included because they are displayed in the TUI (even though they aren't sent to the LLM), and leaving leaked reasoning visible is the exact problem this tool solves.

Safety

  • Creates a one-time .bak2 backup before writing.
  • Writes through a temporary file and atomic rename.
  • Re-opens the repaired file with Pi's SessionManager to validate it.
  • Refuses to modify the loaded session unless --force-live is supplied.

Development

npm install
npm test
npm run typecheck
npm pack --dry-run

Releasing (maintainers)

CI publishes to npm via OIDC trusted publishing — no npm token involved. To cut a release:

  1. Bump version in package.json.
  2. Commit, then tag vX.Y.Z matching that version and push both:
    git tag -a vX.Y.Z -m "vX.Y.Z"
    git push origin main
    git push origin vX.Y.Z
    
  3. CI runs tests, verifies the tag matches package.json's version, then publishes via OIDC. Provenance is generated automatically.

The npm package's Trusted Publisher is configured to only accept publishes from this repo's .github/workflows/ci.yml workflow. Publishing access via classic/granular tokens is disabled on npmjs.com ("Require two-factor authentication and disallow tokens"), so a compromised or misconfigured token cannot publish a release.