pi-smart-compact 10.1.5 → 10.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/dist/app/context-attention.d.ts +26 -0
- package/dist/app/context-attention.d.ts.map +1 -0
- package/dist/constants.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +85 -1
- package/dist/rtk.js +1 -1
- package/docs/configuration.md +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [10.2.0] - 2026-10-05
|
|
6
|
+
|
|
7
|
+
### Release approval
|
|
8
|
+
|
|
9
|
+
- Minor release approved by the release owner after the deterministic gates
|
|
10
|
+
on the exact candidate. No version-specific applied-canary cohort or live
|
|
11
|
+
provider run exists for `10.2.0`; the feature is evidenced by unit tests
|
|
12
|
+
only. The note is gated by `Navigation guide` (`contextGuidanceEnabled`)
|
|
13
|
+
and turns off with it.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **Context attention.** Context pressure used to reach the model only through
|
|
18
|
+
the human status line and `smart_context status` results, so the anchor,
|
|
19
|
+
checkpoint/rewind, trim and compaction tools sat idle until a person asked
|
|
20
|
+
for them. The extension now sends the model one short note when usage
|
|
21
|
+
enters the cleanup band and one more at the compaction band, naming only
|
|
22
|
+
the actions available right now: `smart_navigation anchor` (with the lazy
|
|
23
|
+
`smart_tools` load step when needed), `smart_context checkpoint`/`rewind`
|
|
24
|
+
and `trim` only when history edits are possible on this model (signed
|
|
25
|
+
Anthropic thinking blocks them), plus whether automatic compaction will
|
|
26
|
+
prepare. Mid-turn the note rides along with the next tool batch; at a turn
|
|
27
|
+
end a cleanup note waits for the next prompt and a compaction note is
|
|
28
|
+
skipped under auto-trigger because settled compaction runs first. One note
|
|
29
|
+
per band per session, re-armed once pressure clears; the note is a tail
|
|
30
|
+
message, so the cached prefix is untouched. Gated by `Navigation guide`
|
|
31
|
+
(`contextGuidanceEnabled`), tool loading and agent tool access.
|
|
32
|
+
|
|
5
33
|
## [10.1.5] - 2026-10-05
|
|
6
34
|
|
|
7
35
|
### Release approval
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context attention: one short note to the model when context pressure enters
|
|
3
|
+
* a band, naming only the actions that are available right now.
|
|
4
|
+
*
|
|
5
|
+
* Pressure used to reach the model only through the human status line and
|
|
6
|
+
* `smart_context status` results, so the navigation, history and compaction
|
|
7
|
+
* tools sat idle until a person asked for them. The note rides along with the
|
|
8
|
+
* next tool batch (steer) during a turn; when a turn ends in the cleanup band
|
|
9
|
+
* it waits for the next prompt instead. One note per band per session,
|
|
10
|
+
* re-armed once pressure clears (compaction, trim, rewind). The note is a
|
|
11
|
+
* tail custom message, so the cached prefix is untouched.
|
|
12
|
+
*/
|
|
13
|
+
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
14
|
+
import type { CompactConfig } from "../types.ts";
|
|
15
|
+
export declare const ATTENTION_CUSTOM_TYPE = "smart-compact-attention";
|
|
16
|
+
type AttentionConfig = Pick<CompactConfig, "contextNavigationEnabled" | "contextGuidanceEnabled" | "toolLoading" | "autoTrigger" | "minContextPercent" | "prepareContextPercent" | "maxContextTokens">;
|
|
17
|
+
export interface ContextAttentionDeps {
|
|
18
|
+
config: () => AttentionConfig;
|
|
19
|
+
/** Agent-driven context changes are permitted and nothing (pivot, running compaction) takes priority. */
|
|
20
|
+
canAgentAct: (ctx: ExtensionContext) => boolean;
|
|
21
|
+
/** A lazy group can still be loaded through `smart_tools`. */
|
|
22
|
+
reachable: (group: "navigation" | "history") => boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare function registerContextAttention(pi: Pick<ExtensionAPI, "on" | "sendMessage" | "getActiveTools">, deps: ContextAttentionDeps): void;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=context-attention.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-attention.d.ts","sourceRoot":"","sources":["../../src/app/context-attention.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEtF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAKjD,eAAO,MAAM,qBAAqB,4BAA4B,CAAC;AAK/D,KAAK,eAAe,GAAG,IAAI,CAAC,aAAa,EACvC,0BAA0B,GAAG,wBAAwB,GAAG,aAAa,GAAG,aAAa,GACnF,mBAAmB,GAAG,uBAAuB,GAAG,kBAAkB,CAAC,CAAC;AAExE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,eAAe,CAAC;IAC9B,yGAAyG;IACzG,WAAW,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,OAAO,CAAC;IAChD,8DAA8D;IAC9D,SAAS,EAAE,CAAC,KAAK,EAAE,YAAY,GAAG,SAAS,KAAK,OAAO,CAAC;CACzD;AAED,wBAAgB,wBAAwB,CACtC,EAAE,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,aAAa,GAAG,gBAAgB,CAAC,EAC/D,IAAI,EAAE,oBAAoB,GACzB,IAAI,CAoCN"}
|
package/dist/constants.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type { CompressionProfile, ProfileConfig } from "./types.ts";
|
|
|
8
8
|
* `package.json#version`. Do not hand-edit this line for releases; bump
|
|
9
9
|
* package.json and run `bun run sync-version`.
|
|
10
10
|
*/
|
|
11
|
-
export declare const VERSION = "10.
|
|
11
|
+
export declare const VERSION = "10.2.0";
|
|
12
12
|
/**
|
|
13
13
|
* Opt-in components that are not installed with the extension: optional peer
|
|
14
14
|
* dependencies in package.json, pinned to the versions the release audit
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAEN,KAAK,YAAY,EAEjB,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAEN,KAAK,YAAY,EAEjB,MAAM,iCAAiC,CAAC;AAmEzC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAyDtE,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,EAAE,EAAE,YAAY,QAomB7D"}
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "@earendil-works/pi-coding-agent";
|
|
6
6
|
|
|
7
7
|
// src/constants.ts
|
|
8
|
-
var VERSION = "10.
|
|
8
|
+
var VERSION = "10.2.0";
|
|
9
9
|
var OPTIONAL_COMPONENTS = {
|
|
10
10
|
mnemopi: { name: "@oh-my-pi/pi-mnemopi", version: "18.3.1", enables: "Mnemopi memory store" },
|
|
11
11
|
bun: { name: "bun", version: "1.4.2", enables: "Mnemopi worker runtime when no Bun 1.3.14+ is on PATH" },
|
|
@@ -16807,6 +16807,85 @@ function createSettledAutoTrigger(options = {}) {
|
|
|
16807
16807
|
return { request, noteCompaction, clear };
|
|
16808
16808
|
}
|
|
16809
16809
|
|
|
16810
|
+
// src/app/context-attention.ts
|
|
16811
|
+
var ATTENTION_CUSTOM_TYPE = "smart-compact-attention";
|
|
16812
|
+
var CONTEXT_TOOL_NAME = "smart_context";
|
|
16813
|
+
var LOADER_TOOL_NAME = "smart_tools";
|
|
16814
|
+
function registerContextAttention(pi, deps) {
|
|
16815
|
+
let noted = null;
|
|
16816
|
+
const clear = () => {
|
|
16817
|
+
noted = null;
|
|
16818
|
+
};
|
|
16819
|
+
pi.on("session_start", clear);
|
|
16820
|
+
pi.on("session_before_switch", clear);
|
|
16821
|
+
pi.on("session_before_fork", clear);
|
|
16822
|
+
pi.on("session_tree", clear);
|
|
16823
|
+
pi.on("message_end", (event, ctx) => {
|
|
16824
|
+
const message = event.message;
|
|
16825
|
+
if (message.role !== "assistant")
|
|
16826
|
+
return;
|
|
16827
|
+
const settings = deps.config();
|
|
16828
|
+
if (!settings.contextNavigationEnabled || !settings.contextGuidanceEnabled || settings.toolLoading === "off")
|
|
16829
|
+
return;
|
|
16830
|
+
const sessionId = resolveSessionId(ctx);
|
|
16831
|
+
const pressure = contextPressure(ctx, settings);
|
|
16832
|
+
const band = pressure.compaction ? "compaction" : pressure.cleanup ? "cleanup" : null;
|
|
16833
|
+
if (!band) {
|
|
16834
|
+
if (noted?.sessionId === sessionId)
|
|
16835
|
+
noted = null;
|
|
16836
|
+
return;
|
|
16837
|
+
}
|
|
16838
|
+
if (noted?.sessionId === sessionId && (noted.band === band || noted.band === "compaction"))
|
|
16839
|
+
return;
|
|
16840
|
+
if (message.content.some((block) => block.type === "toolCall" && (block.name === NAVIGATION_TOOL_NAME || block.name === CONTEXT_TOOL_NAME)))
|
|
16841
|
+
return;
|
|
16842
|
+
const midTurn = message.stopReason === "toolUse";
|
|
16843
|
+
if (!midTurn && band === "compaction" && settings.autoTrigger)
|
|
16844
|
+
return;
|
|
16845
|
+
if (!deps.canAgentAct(ctx))
|
|
16846
|
+
return;
|
|
16847
|
+
const active = new Set(pi.getActiveTools());
|
|
16848
|
+
const content = renderAttention(band, pressure.percent, settings, ctx, active, deps.reachable);
|
|
16849
|
+
if (!content)
|
|
16850
|
+
return;
|
|
16851
|
+
noted = { sessionId, band };
|
|
16852
|
+
pi.sendMessage({ customType: ATTENTION_CUSTOM_TYPE, content, display: true, details: { band, percent: pressure.percent } }, { deliverAs: midTurn ? "steer" : "nextTurn" });
|
|
16853
|
+
});
|
|
16854
|
+
}
|
|
16855
|
+
function renderAttention(band, percent, settings, ctx, active, reachable) {
|
|
16856
|
+
const lines = [];
|
|
16857
|
+
const load = (group, tool) => active.has(tool) ? "" : reachable(group) && active.has(LOADER_TOOL_NAME) ? ` Load it first: ${LOADER_TOOL_NAME} load ${group}.` : null;
|
|
16858
|
+
const navigation = load("navigation", NAVIGATION_TOOL_NAME);
|
|
16859
|
+
const history = load("history", CONTEXT_TOOL_NAME);
|
|
16860
|
+
if (navigation !== null) {
|
|
16861
|
+
lines.push((band === "compaction" ? `- Anchor now: ${NAVIGATION_TOOL_NAME} anchor with a name and a concise handoff (done / in progress / next step). The summary starts from it and the prompt cache stays warm up to it.` : `- Finishing a unit of work? ${NAVIGATION_TOOL_NAME} anchor with a concise handoff; safe cleanup is queued automatically and the prefix up to the anchor stays cached.`) + navigation);
|
|
16862
|
+
}
|
|
16863
|
+
if (history !== null) {
|
|
16864
|
+
const branch = ctx.sessionManager.getBranch();
|
|
16865
|
+
let trimmable = 0;
|
|
16866
|
+
let blocked = false;
|
|
16867
|
+
try {
|
|
16868
|
+
const plan = planContextTrim(branch, inspectContext(branch, resolveSessionId(ctx)).checkpoint?.originId, { readerApi: ctx.model?.api });
|
|
16869
|
+
blocked = Boolean(plan.blockedReason);
|
|
16870
|
+
trimmable = plan.entries.filter((entry) => entry.type === "context_edit").length;
|
|
16871
|
+
} catch {
|
|
16872
|
+
blocked = true;
|
|
16873
|
+
}
|
|
16874
|
+
if (!blocked) {
|
|
16875
|
+
if (trimmable > 0)
|
|
16876
|
+
lines.push(`- ${CONTEXT_TOOL_NAME} trim: ${trimmable} archived tool output${trimmable === 1 ? "" : "s"} eligible now.${history}`);
|
|
16877
|
+
lines.push(`- Starting a large read-only detour? ${CONTEXT_TOOL_NAME} checkpoint first, then rewind(report) when done keeps the findings and drops the research.${trimmable > 0 ? "" : history}`);
|
|
16878
|
+
}
|
|
16879
|
+
}
|
|
16880
|
+
if (!lines.length)
|
|
16881
|
+
return null;
|
|
16882
|
+
const where = percent === null ? "" : ` ${Math.round(percent)}% of the policy window`;
|
|
16883
|
+
const head = band === "compaction" ? `Context attention:${where} (compaction band). ` + (settings.autoTrigger ? "Compaction prepares now and applies when the turn settles." : "Automatic compaction is off here; the user runs /smart-compact.") : `Context attention:${where} (cleanup band). ` + (settings.autoTrigger ? `Automatic compaction prepares at ${settings.minContextPercent}%.` : "Automatic compaction is off here.");
|
|
16884
|
+
return `${head}
|
|
16885
|
+
${lines.join(`
|
|
16886
|
+
`)}`;
|
|
16887
|
+
}
|
|
16888
|
+
|
|
16810
16889
|
// src/app/host-cache-ledger.ts
|
|
16811
16890
|
var FOREIGN_REBUILD_WARN_COUNT = 3;
|
|
16812
16891
|
var num = (value) => typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
|
|
@@ -25023,6 +25102,11 @@ function smartCompactExtension(pi) {
|
|
|
25023
25102
|
hostCache.noteCacheWarm(at);
|
|
25024
25103
|
}
|
|
25025
25104
|
});
|
|
25105
|
+
registerContextAttention(pi, {
|
|
25106
|
+
config: automaticConfig,
|
|
25107
|
+
canAgentAct: (ctx) => policy.snapshot().agentToolAccess !== "disabled" && !pivotQueued(ctx) && !isRunning.isSessionActive(resolveSessionId(ctx)),
|
|
25108
|
+
reachable: (group) => toolExposure.reachable(group)
|
|
25109
|
+
});
|
|
25026
25110
|
registerSmartCompactCommand(pi, {
|
|
25027
25111
|
pendingRef,
|
|
25028
25112
|
runLock: isRunning,
|
package/dist/rtk.js
CHANGED
|
@@ -198,7 +198,7 @@ class SecretScrubber {
|
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
// src/constants.ts
|
|
201
|
-
var VERSION = "10.
|
|
201
|
+
var VERSION = "10.2.0";
|
|
202
202
|
var OPTIONAL_COMPONENTS = {
|
|
203
203
|
mnemopi: { name: "@oh-my-pi/pi-mnemopi", version: "18.3.1", enables: "Mnemopi memory store" },
|
|
204
204
|
bun: { name: "bun", version: "1.4.2", enables: "Mnemopi worker runtime when no Bun 1.3.14+ is on PATH" },
|
package/docs/configuration.md
CHANGED
|
@@ -454,7 +454,7 @@ Settings → **Agent tools & navigation**.
|
|
|
454
454
|
| `contextPivotEnabled` | `Return to an anchor` | `true` | Returning to an anchor on a new branch with a required carryover. |
|
|
455
455
|
| `contextAnchorCacheEnabled` | `Anchor prompt cache` | `true` | Anthropic models: keeps a prompt-cache marker on the newest anchor. |
|
|
456
456
|
| `contextAnchorStatusEnabled` | `Anchor status` | `true` | Shows the newest anchor on this branch in Pi's footer; display only. |
|
|
457
|
-
| `contextGuidanceEnabled` | `Navigation guide` | `true` | Lets you or the agent open the navigation guide on request; it is never added to a request otherwise. |
|
|
457
|
+
| `contextGuidanceEnabled` | `Navigation guide` | `true` | Lets you or the agent open the navigation guide on request; it is never added to a request otherwise. Also enables context attention: one short note to the model when context usage enters the cleanup band and again at the compaction band, naming only the context tools available right now (anchor; checkpoint/rewind and trim when history edits are possible). Re-armed once pressure clears. |
|
|
458
458
|
|
|
459
459
|
Group permissions apply in both `lazy` and `eager` modes: `compaction` follows
|
|
460
460
|
`agentToolAccess`, `memory` needs `contextGraphEnabled` or a non-local
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-smart-compact",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.2.0",
|
|
4
4
|
"description": "Pi Continuity — context hygiene and session continuity for Pi Coding Agent: recoverable cleanup, checkpoints, memory and verified compaction.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "bun@1.4.2",
|