npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

pi-context-epochs

v0.1.0

Published

Model-driven context epochs for Pi: same-session fresh working contexts without LLM-generated summaries. Provides new_context, context_notes and context_history primitives.

Downloads

117

Readme

pi-context-epochs

Model-driven context epochs for Pi: start a fresh working context inside the same session, with no LLM-generated summary, while the full transcript stays append-only, durable, searchable, and recoverable.

Inspired by OpenAI Codex's context management work (openai/codex#27488, the new_context tool and context-window replacement), implemented as a thin Pi extension using Pi's own durable compaction machinery.

Motivation

Long agentic sessions exhaust their context. The two options Pi ships are:

  • Compaction (/compact, auto-threshold): an LLM summarizes old messages. That costs a summarization call, is lossy, and replaces exact history with a paraphrase.
  • New session (/new, ctx.newSession()): a different session file. Identity, notes, and continuity are lost.

Neither is "retire the working set and continue". The missing primitive is a durable context boundary: old messages leave the model's active context, the transcript keeps everything, and the session keeps its identity. Pi upstream does not yet expose ctx.newContext() (proposal, auto-closed as earendil-works/pi#8972).

This package provides that primitive as an extension by reusing Pi's own compaction projection: an epoch boundary is a real CompactionEntry whose kept-entry id can never match a real entry, so Pi itself - context reconstruction, token accounting, auto-compaction checks, /tree, fork, resume, reload - treats everything before the boundary as retired.

Pi session (one JSONL file, append-only tree)
│
├── epoch 0   user/assistant/tool messages
├── epoch 1   user/assistant/tool messages
├── epoch 2   ← active model working context
├── Notes     ← model-curated, session-scoped, branch-aware
└── History   ← full transcript; retired epochs are still searchable

What the model gets

Exactly three tools (plus a /epoch command for the human):

| Tool | Purpose | |------|---------| | new_context | End the current epoch and continue the same session in a fresh working context. No arguments. No summary. | | context_notes | list / read / write / delete small, session-scoped notes that survive rollovers. | | context_history | search (lexical) and read (by stable entry ref) the durable transcript, including retired epochs. |

new_context semantics

Calling new_context arms a rollover. When the current agent run settles, the extension:

  1. Asks Pi to compact, and (via the session_before_compact hook) supplies a package-owned, deterministic boundary entry - no LLM call:
    • summary: a small <context_epoch> marker (epoch id, previous epoch id, trigger, current note keys, the verbatim latest user request as a continuation anchor, one re-grounding instruction).
    • firstKeptEntryId: a value that can never match a real entry id, so Pi's projection keeps only the marker plus everything after it.
    • details: { kind: "pi-context-epochs/epoch", version: 1, epochId, previousEpochId, epochIndex, trigger, createdAt }.
  2. Pi appends the entry, rebuilds the agent's active context from its own session projection, and emits session_compact (the extension verifies the persisted entry is really package-owned before continuing).
  3. A one-line continuation nudge starts the first turn of the new epoch.

Triggers recorded in the boundary: model (the tool), manual (/epoch new), threshold (Pi auto-compaction threshold), overflow (provider context-overflow recovery).

The rollover never calls a summarizer. The only LLM cost after a rollover is the model's own continuation turn.

Notes philosophy

Notes are for non-reconstructable semantic state: explicit user decisions, rejected approaches and why, non-obvious constraints, unresolved blockers, acceptance criteria, external side effects. Things that are cheap to re-derive (source files, git, tests, package metadata, history) should be re-derived, not copied. Notes are session-scoped: they end with the session; there is no cross-session memory.

Notes persist as Pi custom entries on the session branch, so /tree and fork replay only the notes that belong to the branch you are on.

History

context_history search does case-insensitive substring matching with a simple score (occurrences + recency + role bias) over the current branch (or the whole file with scope: "session"). No embeddings, no vector DB, no background indexer - the session entries are the source of truth. Results carry stable refs (Pi entry ids). read returns one entry plus a bounded neighborhood. Reasoning/thinking blocks are never returned; tool results are tightly truncated; total read size is bounded (historyMaxChars, default 16k chars).

What the runtime gets (the model does not see this)

  • Context pressure reminders - one-shot per epoch per band, computed by the runtime from ctx.getContextUsage() against the model's real contextWindow (no per-turn counters, no prompt churn):
    • soft at ≤ 25% remaining (configurable): "preserve non-reconstructable state; start a new context when the working set is no longer useful"
    • critical at ≤ 10% remaining: only sent when autoRollover is off - otherwise that zone is owned by Pi's threshold/overflow machinery (see below), and a steered critical reminder would land stale in the fresh epoch.
  • Automatic rollover - when Pi's auto-compaction threshold fires (or a provider overflow needs recovery), the extension converts the compaction into an epoch boundary instead of a summarization call. Loop-safety: after the boundary the active context is tiny, so the threshold check cannot re-fire; tests cover the no-loop property.
  • Verification - after any rollover, the extension checks that the persisted compaction entry is package-owned. If another extension overwrote the compaction result, it fails closed: no continuation is sent, and the conflict is surfaced.
  • Conflict scan - at startup the package warns about installed extensions known to also replace compaction results (pi-agenticoding, pi-context, pi-context-prune, billion-context-pi, pi-codex-compaction, pi-codex-compact, pi-session-continuity, pi-continue).

Why the boundary is "real"

buildContextEntries() - Pi's single projection used for prompt building, token estimation, auto-compaction decisions, reload, resume, and tree navigation - keeps, for the latest compaction on the branch: the compaction entry itself, entries from firstKeptEntryId (never matches ⇒ none), and everything appended after it. Therefore:

  • Active context: marker + new-epoch messages only.
  • Token accounting: estimated from the projected context; the stale-usage check in Pi's _checkCompaction prevents re-triggering off pre-boundary usage.
  • Reload / resume: SessionManager.open(file) reproduces the same projection - the boundary is in the file, not in extension memory.
  • /tree / fork: the boundary is an ordinary branch entry; switching branches switches the epoch sequence (and notes) to that branch.
  • Durability: the raw JSONL keeps every pre-boundary entry, append-only.

Installation

pi install /Users/zzzhizhi/Developer/zzzhizhia/pi-context-epochs
pi list          # should show pi-context-epochs

Local path installs are referenced in place (no copying), so editing the project directory is the update; restart pi or run /reload to pick up changes.

Uninstall:

pi remove /Users/zzzhizhi/Developer/zzzhizhia/pi-context-epochs

Usage

  • Ask the model to "start a new context" / "roll over" - it calls new_context (writing essential notes first).
  • /epoch - status (epoch, usage, pressure, notes, last rollover).
  • /epoch new - user-triggered rollover (no summary).
  • /epoch notes / /epoch history / /epoch debug - notes list, epoch boundaries, diagnostics (raw vs active context sizes, boundary details, conflicts).

Headless/print mode works; continuation waits for the follow-up run to settle there.

Configuration

~/.pi/agent/context-epochs.json (optional; defaults are safe, invalid values warn and fall back):

{
  "enabled": true,
  "softRemainingRatio": 0.25,
  "criticalRemainingRatio": 0.1,
  "autoRollover": true,
  "historySearchLimit": 8,
  "historyReadAround": 2,
  "historyMaxChars": 16000,
  "noteMaxChars": 8000,
  "continuationAnchorMaxChars": 2000
}

Compatibility & limitations

  • Manual /compact is untouched (native summarization is preserved) unless the instructions string is the package's internal marker.
  • Competing compaction rewriters: last session_before_compact handler wins in Pi. The extension warns at startup and fails closed at verification time; it never sends a continuation for a boundary it does not own.
  • Tiny sessions: a rollover needs content before Pi's cut point (keepRecentTokens, default 20k). new_context pre-checks this and refuses gracefully on very small contexts instead of creating a meaningless boundary.
  • Not checkpoint/rewind: epochs replace the whole active working context generation; they do not snapshot or restore granular states, and they do not interfere with git-checkpoint style tools.
  • Thinking/reasoning content is never exposed through history reads.

How this differs from Pi compaction

Pi compaction summarizes (LLM call, paraphrase). This package retires: no summary, no summarizer cost, exact history still retrievable. It rides on Pi's compaction path because that path is the one place where pi rebuilds agent state from the durable session projection - which is exactly what "same session, fresh context" needs.

Relation to Codex's experimental_mode context management

Parity: same-session fresh working context (new_context), token-budget-style sparse pressure reminders computed by the runtime, no planner/orchestrator machinery. Differences: Codex's runtime replaces the active history as a first-class session operation and recomputes usage natively; here the boundary is expressed through Pi's compaction projection (identical observable behavior, different mechanism), and Codex's budget reminder cadence/labels differ in detail. This package does not clone Codex prompts or role workflows.

Development

npm install
npm run typecheck
npm test          # unit + SDK integration tests (scripted model, no network)
npm run check     # typecheck + tests
npm run measure   # model-facing overhead measurement

License

MIT