Luigit
repositories / pi-ext

pi-ext

bugabingas pi extensions

owned by admin

extensions/decay/README.md

Raw
Rendered preview

Decay

Recency-weighted structured compaction for Pi.

Load extensions/decay/index.ts through Pi's package discovery.

Set the optional compaction model in Pi settings:

{
  "decay": {
    "model": "provider/classifier-model",
    "summarizerModel": "provider/summarizer-model"
  }
}

Decay reads decay.model and decay.summarizerModel from trusted project settings, then user settings. Project settings apply only when Pi trusts the project, and each key resolves independently, so a project model keeps the user summarizerModel. There are no flags or environment variables for these settings. A project null explicitly unsets that key and does not fall back to the user value. A value that is not null or a non-empty string warns that the setting must be provider/model, null, or omitted, never falls through to a lower-priority source, and uses Pi's default compactor.

Omit model or set it to null to use the current session model. If an explicit model is unavailable or fails during classification/summarization, Decay retries that stage once with the current session model. Quota and rate-limit errors follow the same fallback path. Omit summarizerModel or set it to null to reuse the classifier model. Decay requests no reasoning effort for openai-codex/gpt-6-luna classification; other classifiers and all summarizers request low reasoning when supported. Pi's /thinking setting does not control these nested requests.

Failed Decay runs delegate to Pi's default compactor and append a bounded decay-diagnostic custom entry containing the outcome, stage, model, sanitized reason, and timestamp. The custom entry is persisted in session JSONL but excluded from model context.

Failure handling differs per stage because only some stages can degrade without inventing memory. Decay groups discarded messages by user exchange where possible, keeps tool-call batches together, and splits oversized exchanges near the chunk token target without splitting individual messages. It classifies these chunks sequentially, with one model request and one record_chunk result per chunk; completed chunks seed the identity catalog for subsequent requests. A transient classifier failure, or a request that omits its chunk, triggers up to two retries of that chunk before falling back. Exact duplicate records for one chunk are tolerated, while conflicting reclassification, records for another chunk, authentication errors, and misconfigured models fall back immediately. Unclassified chunks are never given default records, since inventing or silently dropping memory would fail invisibly.

A summarizer failure salvages instead of falling back: Decay renders the ranked atoms deterministically into the same section structure without a model call, marks the compaction degraded: "summarizer", and records a salvage diagnostic. Salvaged summaries keep the classified facts, provenance, ranking, and recurrence identity, and lose only prose synthesis.

Repeated compactions provide the classifier a bounded prior-atom identity catalog so paraphrased facts can reuse exact recurrence keys without counting catalog entries as new occurrences.

Interactive progress uses a passive, borderless five-row widget above Pi's editor, preserving native steering submission and Escape cancellation during compaction. The aligned CTX, FACTS, and NEW maps use compact human-readable counts and reversed semantic colors so overlaid labels remain legible across themes. Classifier records replace muted pending cells with durable and context regions as they arrive. After reconciliation, selected canonical facts turn to the accent color before streamed summary cells grow at the start of NEW. CTX and NEW share a token scale, so the retained suffix keeps the same approximate width and follows the growing summary in the resulting context.

keepRecentTokens is Pi's configured target, not an exact count or minimum guarantee. Pi chooses whole-entry boundaries, which can retain more or fewer tokens than the target. Decay preserves firstKeptEntryId unchanged and does not send the retained suffix to its classifier. The displayed retained count and estimatedKeptTokens details field use Pi's message-token estimator over the actual retained suffix, including older summaries when present. ~ marks estimates; unavailable boundaries display ?, never the configured target as a measured count.

Historical design: /system view PX-RESEARCH-F1EA6810. Earlier visual artifacts remain in Git history. The current widget uses five contiguous lines at every terminal height; aligned evidence-driven maps replace that plan's eight-line design. That plan's blanket "any non-abort failure uses default compaction" rule is superseded by the staged policy above.

Debug

Opt in through debug logging. compaction.plan records shard counts, estimated source sizes, oversized shards, prior atom count, and Pi's retention target. Each classifier.request span records a shard and attempt ordinal, bounded source/catalog sizes, model role, duration, stop reason, accepted versus received records, atom counts, and any reported usage. classifier.decision records retries, model fallback, and exhaustion without logging provider errors. compaction.memory records active and selected atom counts, kind distribution, and allocation pressure. Each summarizer.request span records allocation size, stop reason, summary size, duration, and reported usage. compaction.outcome records the final stage and result; numeric run ordinals correlate records within one loaded extension runtime. No source text, atom contents, keys, file paths, raw errors, model identifiers, or provider request IDs go into these debug records. Reported usage can be absent or incomplete for failed requests, and structural counts cannot establish whether the classifier retained the right facts.

# Decay

Recency-weighted structured compaction for Pi.

Load `extensions/decay/index.ts` through Pi's package discovery.

Set the optional compaction model in Pi settings:

```json
{
  "decay": {
    "model": "provider/classifier-model",
    "summarizerModel": "provider/summarizer-model"
  }
}
```

Decay reads `decay.model` and `decay.summarizerModel` from trusted project settings, then user settings.
Project settings apply only when Pi trusts the project, and each key resolves independently, so a project `model` keeps the user `summarizerModel`.
There are no flags or environment variables for these settings.
A project `null` explicitly unsets that key and does not fall back to the user value.
A value that is not `null` or a non-empty string warns that the setting must be provider/model, null, or omitted, never falls through to a lower-priority source, and uses Pi's default compactor.

Omit `model` or set it to `null` to use the current session model.
If an explicit model is unavailable or fails during classification/summarization, Decay retries that stage once with the current session model.
Quota and rate-limit errors follow the same fallback path.
Omit `summarizerModel` or set it to `null` to reuse the classifier model.
Decay requests no reasoning effort for `openai-codex/gpt-6-luna` classification; other classifiers and all summarizers request `low` reasoning when supported.
Pi's `/thinking` setting does not control these nested requests.

Failed Decay runs delegate to Pi's default compactor and append a bounded `decay-diagnostic` custom entry containing the outcome, stage, model, sanitized reason, and timestamp.
The custom entry is persisted in session JSONL but excluded from model context.

Failure handling differs per stage because only some stages can degrade without inventing memory.
Decay groups discarded messages by user exchange where possible, keeps tool-call batches together, and splits oversized exchanges near the chunk token target without splitting individual messages.
It classifies these chunks sequentially, with one model request and one `record_chunk` result per chunk; completed chunks seed the identity catalog for subsequent requests.
A transient classifier failure, or a request that omits its chunk, triggers up to two retries of that chunk before falling back.
Exact duplicate records for one chunk are tolerated, while conflicting reclassification, records for another chunk, authentication errors, and misconfigured models fall back immediately.
Unclassified chunks are never given default records, since inventing or silently dropping memory would fail invisibly.

A summarizer failure salvages instead of falling back: Decay renders the ranked atoms deterministically into the same section structure without a model call, marks the compaction `degraded: "summarizer"`, and records a `salvage` diagnostic.
Salvaged summaries keep the classified facts, provenance, ranking, and recurrence identity, and lose only prose synthesis.

Repeated compactions provide the classifier a bounded prior-atom identity catalog so paraphrased facts can reuse exact recurrence keys without counting catalog entries as new occurrences.

Interactive progress uses a passive, borderless five-row widget above Pi's editor, preserving native steering submission and Escape cancellation during compaction.
The aligned `CTX`, `FACTS`, and `NEW` maps use compact human-readable counts and reversed semantic colors so overlaid labels remain legible across themes.
Classifier records replace muted pending cells with durable and context regions as they arrive.
After reconciliation, selected canonical facts turn to the accent color before streamed summary cells grow at the start of `NEW`.
`CTX` and `NEW` share a token scale, so the retained suffix keeps the same approximate width and follows the growing summary in the resulting context.

`keepRecentTokens` is Pi's configured target, not an exact count or minimum guarantee.
Pi chooses whole-entry boundaries, which can retain more or fewer tokens than the target.
Decay preserves `firstKeptEntryId` unchanged and does not send the retained suffix to its classifier.
The displayed retained count and `estimatedKeptTokens` details field use Pi's message-token estimator over the actual retained suffix, including older summaries when present.
`~` marks estimates; unavailable boundaries display `?`, never the configured target as a measured count.

Historical design: `/system view PX-RESEARCH-F1EA6810`.
Earlier visual artifacts remain in Git history.
The current widget uses five contiguous lines at every terminal height; aligned evidence-driven maps replace that plan's eight-line design.
That plan's blanket "any non-abort failure uses default compaction" rule is superseded by the staged policy above.

## Debug

Opt in through [debug logging](../DEBUG.md).
`compaction.plan` records shard counts, estimated source sizes, oversized shards, prior atom count, and Pi's retention target.
Each `classifier.request` span records a shard and attempt ordinal, bounded source/catalog sizes, model role, duration, stop reason, accepted versus received records, atom counts, and any reported usage.
`classifier.decision` records retries, model fallback, and exhaustion without logging provider errors.
`compaction.memory` records active and selected atom counts, kind distribution, and allocation pressure.
Each `summarizer.request` span records allocation size, stop reason, summary size, duration, and reported usage.
`compaction.outcome` records the final stage and result; numeric run ordinals correlate records within one loaded extension runtime.
No source text, atom contents, keys, file paths, raw errors, model identifiers, or provider request IDs go into these debug records.
Reported usage can be absent or incomplete for failed requests, and structural counts cannot establish whether the classifier retained the right facts.