@diegopetrucci/pi-extensions 0.1.66 → 0.1.68
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/extensions/code-reviewer/index.ts +3 -1
- package/extensions/code-reviewer/package.json +1 -1
- package/extensions/contrarian/index.ts +4 -11
- package/extensions/contrarian/package.json +1 -1
- package/extensions/dynamic-context-pruning/README.md +24 -15
- package/extensions/dynamic-context-pruning/index.ts +26 -11
- package/extensions/dynamic-context-pruning/package.json +1 -1
- package/extensions/oracle/index.ts +3 -11
- package/extensions/oracle/package.json +1 -1
- package/package.json +4 -4
|
@@ -23,6 +23,7 @@ const THINKING_LEVELS = ["off", "minimal", "low", "medium", "high", "xhigh", "ma
|
|
|
23
23
|
type ThinkingLevel = (typeof THINKING_LEVELS)[number];
|
|
24
24
|
type ThinkingLevelMap = Partial<Record<ThinkingLevel, unknown | null>>;
|
|
25
25
|
const CODE_REVIEWER_MODEL_PREFERENCES = [
|
|
26
|
+
"gpt-6-astra",
|
|
26
27
|
"gpt-5.6-sol",
|
|
27
28
|
"gpt-5.6-terra",
|
|
28
29
|
"gpt-5.6-luna",
|
|
@@ -56,8 +57,9 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
56
57
|
"claude-sonnet-4-6",
|
|
57
58
|
"claude-sonnet-4-5",
|
|
58
59
|
],
|
|
59
|
-
openai: ["gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-5.5", "gpt-5", "gpt-4.1", "o3", "o4-mini"],
|
|
60
|
+
openai: ["gpt-6-astra", "gpt-5.6-sol", "gpt-5.6-terra", "gpt-5.6-luna", "gpt-5.5", "gpt-5", "gpt-4.1", "o3", "o4-mini"],
|
|
60
61
|
"openai-codex": [
|
|
62
|
+
"gpt-6-astra",
|
|
61
63
|
"gpt-5.6-sol",
|
|
62
64
|
"gpt-5.6-terra",
|
|
63
65
|
"gpt-5.6-luna",
|
|
@@ -105,6 +105,7 @@ const CONTRARIAN_STATUS_ID = "contrarian";
|
|
|
105
105
|
const CONTRARIAN_WIDGET_ID = "contrarian";
|
|
106
106
|
const CONTRARIAN_CONFIG_FILE = "contrarian.json";
|
|
107
107
|
const CONTRARIAN_MODEL_PREFERENCES = [
|
|
108
|
+
"gpt-6-astra",
|
|
108
109
|
"gpt-5.6-sol",
|
|
109
110
|
"gpt-5.6-terra",
|
|
110
111
|
"gpt-5.6-luna",
|
|
@@ -247,21 +248,16 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
247
248
|
"claude-fable-5",
|
|
248
249
|
"claude-opus-4.8",
|
|
249
250
|
"claude-opus-4.7",
|
|
250
|
-
"
|
|
251
|
-
"claude-opus-4.5",
|
|
251
|
+
"gpt-6-astra",
|
|
252
252
|
"gpt-5.6-sol",
|
|
253
253
|
"gpt-5.6-terra",
|
|
254
254
|
"gpt-5.6-luna",
|
|
255
255
|
"gpt-5.5",
|
|
256
256
|
"gpt-5.4",
|
|
257
257
|
"gpt-5.3-codex",
|
|
258
|
-
"gpt-5.2-codex",
|
|
259
|
-
"gpt-5.2",
|
|
260
|
-
"gemini-3.1-pro-preview",
|
|
261
258
|
"gemini-3.5-flash",
|
|
262
259
|
"claude-sonnet-5",
|
|
263
260
|
"claude-sonnet-4.6",
|
|
264
|
-
"claude-sonnet-4.5",
|
|
265
261
|
"gpt-5-mini",
|
|
266
262
|
"kimi-k3",
|
|
267
263
|
"kimi-k2.7-code",
|
|
@@ -323,6 +319,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
323
319
|
"zai-glm-5-2",
|
|
324
320
|
],
|
|
325
321
|
openai: [
|
|
322
|
+
"gpt-6-astra",
|
|
326
323
|
"gpt-5.6-sol",
|
|
327
324
|
"gpt-5.6-terra",
|
|
328
325
|
"gpt-5.6-luna",
|
|
@@ -342,6 +339,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
342
339
|
"gpt-5-mini",
|
|
343
340
|
],
|
|
344
341
|
"openai-codex": [
|
|
342
|
+
"gpt-6-astra",
|
|
345
343
|
"gpt-5.6-sol",
|
|
346
344
|
"gpt-5.6-terra",
|
|
347
345
|
"gpt-5.6-luna",
|
|
@@ -400,9 +398,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
400
398
|
"anthropic/claude-fable-5",
|
|
401
399
|
"~anthropic/claude-fable-latest",
|
|
402
400
|
"anthropic/claude-opus-4.8",
|
|
403
|
-
"anthropic/claude-opus-4.8-fast",
|
|
404
401
|
"anthropic/claude-opus-4.7",
|
|
405
|
-
"anthropic/claude-opus-4.7-fast",
|
|
406
402
|
"anthropic/claude-opus-4.6",
|
|
407
403
|
"anthropic/claude-opus-4.5",
|
|
408
404
|
"anthropic/claude-opus-4.1",
|
|
@@ -528,7 +524,6 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
528
524
|
"grok-4.6",
|
|
529
525
|
"grok-4.5",
|
|
530
526
|
"grok-4.3",
|
|
531
|
-
"grok-build-0.1",
|
|
532
527
|
],
|
|
533
528
|
xiaomi: ["mimo-v2.5-pro-ultraspeed", "mimo-v2.5-pro", "mimo-v2.5"],
|
|
534
529
|
"xiaomi-token-plan-ams": ["mimo-v2.5-pro", "mimo-v2.5"],
|
|
@@ -541,9 +536,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
541
536
|
"deepseek-ai/deepseek-v4-pro-0813",
|
|
542
537
|
"moonshotai/kimi-k2.6",
|
|
543
538
|
"minimaxai/minimax-m3",
|
|
544
|
-
"openai/gpt-oss-120b",
|
|
545
539
|
"nvidia/nemotron-3-nano-omni-30b-a3b-reasoning",
|
|
546
|
-
"nvidia/nemotron-3-nano-30b-a3b",
|
|
547
540
|
],
|
|
548
541
|
zai: [
|
|
549
542
|
"glm-5.3",
|
|
@@ -130,10 +130,10 @@ Where `r` is `gate.cachedPriceRatio` — the fraction of full price still paid
|
|
|
130
130
|
for cached tokens (default `0.1`, i.e. cached tokens cost ~10% of fresh
|
|
131
131
|
tokens). `breakEvenCalls` is how many subsequent LLM calls are needed to
|
|
132
132
|
recoup the one-time cache-bust cost via the recurring saving. The gate accepts
|
|
133
|
-
a batch of candidates only if `breakEvenCalls
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
[Roadmap](#roadmap) evidence).
|
|
133
|
+
a batch of candidates only if `breakEvenCalls` is at most the effective
|
|
134
|
+
threshold for the current state (`idle=22`, `mid_loop=1` by default,
|
|
135
|
+
calibrated from the representative-corpus benchmark — see the calibration
|
|
136
|
+
note under [Configuration](#configuration) and the [Roadmap](#roadmap) evidence).
|
|
137
137
|
|
|
138
138
|
All candidates proposed in the same `context` call share one cache bust (since
|
|
139
139
|
a prompt cache is a single linear prefix), so they're evaluated and
|
|
@@ -179,7 +179,7 @@ branch:
|
|
|
179
179
|
/context-pruning gate <on|off|always-apply>
|
|
180
180
|
```
|
|
181
181
|
|
|
182
|
-
- `status`: enabled state, gate mode/
|
|
182
|
+
- `status`: enabled state, gate mode/effective per-state thresholds/ratio, per-strategy on/off
|
|
183
183
|
state, protection counts, last call's raw/effective/saved token snapshot,
|
|
184
184
|
and current context usage.
|
|
185
185
|
- `stats`: cumulative tokens saved, overall and per strategy.
|
|
@@ -223,7 +223,7 @@ never required to exist. Full shape, with defaults:
|
|
|
223
223
|
"mode": "on",
|
|
224
224
|
"cachedPriceRatio": 0.1,
|
|
225
225
|
"breakEvenThreshold": 22,
|
|
226
|
-
"breakEvenThresholdByState": { "idle": 22, "mid_loop":
|
|
226
|
+
"breakEvenThresholdByState": { "idle": 22, "mid_loop": 1 }
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
229
|
```
|
|
@@ -243,7 +243,8 @@ Notes:
|
|
|
243
243
|
break-even math (`gate.*`), which is a separate, later check on whatever
|
|
244
244
|
survives this floor.
|
|
245
245
|
- `gate.breakEvenThresholdByState` lets `idle` vs `mid_loop` agent states use
|
|
246
|
-
different thresholds;
|
|
246
|
+
different thresholds; `idle` defaults to `22` and
|
|
247
|
+
`mid_loop` defaults to `1`. Real
|
|
247
248
|
mid-loop/idle detection is wired through the `context` event handler
|
|
248
249
|
(pe-zy4s): the state is classified straight from the message payload —
|
|
249
250
|
`idle` if the most recent relevant message is a user message (this is the
|
|
@@ -253,9 +254,15 @@ Notes:
|
|
|
253
254
|
runtime-observable definition and found the state-split REVERSED from an
|
|
254
255
|
earlier turn-end-based analysis: at r=0.1, `idle` candidates now carry
|
|
255
256
|
essentially all the realized net benefit and `mid_loop` candidates carry
|
|
256
|
-
essentially none.
|
|
257
|
-
|
|
258
|
-
|
|
257
|
+
essentially none. At r=0.1, the measured corpus therefore supports a
|
|
258
|
+
conservative `mid_loop=1` default, while `idle` remains `22`. Mid-loop
|
|
259
|
+
pruning can amortize over enough subsequent calls, but the observed
|
|
260
|
+
candidates did not justify a more permissive threshold. Turn-start
|
|
261
|
+
classification does not imply the provider cache is cold. The reported
|
|
262
|
+
field capture (2026-09-08: a mid_loop prune at `T=22` invalidated 81% of a
|
|
263
|
+
warm request prefix between consecutive LLM calls separated only by a
|
|
264
|
+
toolResult) illustrates cache invalidation, not proof that amortization is
|
|
265
|
+
impossible. Set `mid_loop` back to `22` to restore the old parity behavior.
|
|
259
266
|
- `gate.breakEvenThreshold`'s default of `22` is calibrated from the
|
|
260
267
|
representative-corpus benchmark at `cachedPriceRatio` r=0.1 (aggressive
|
|
261
268
|
prompt caching, the common case) — see [Roadmap](#roadmap) for the full
|
|
@@ -448,11 +455,13 @@ re-derived on the representative corpus (460 gate-eligible candidates on the
|
|
|
448
455
|
current `~/.the-last-harness/agent/sessions` corpus). The split **reverses**:
|
|
449
456
|
at r=0.1, `idle` (T=22, ~20.6k realized net benefit) now carries essentially
|
|
450
457
|
all the value, and `mid_loop` (T=1, ~0 realized net benefit) carries
|
|
451
|
-
essentially none.
|
|
452
|
-
is shown ~worthless),
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
458
|
+
essentially none. Under that ticket's decision rule (stricter idle default
|
|
459
|
+
only if idle is shown ~worthless), parity (`22`/`22`) was retained at the time.
|
|
460
|
+
The 2026-09-08 follow-up supersedes that default with `idle=22` / `mid_loop=1`,
|
|
461
|
+
using the measured mid-loop result to choose a conservative threshold (see
|
|
462
|
+
[Configuration](#configuration) for the evidence and limitations). The table
|
|
463
|
+
above is retained as the historical turn-END-definition record; it no longer
|
|
464
|
+
reflects how the runtime classifies agent state.
|
|
456
465
|
|
|
457
466
|
**This reframes, rather than weakens, the case for v2.** Small deterministic
|
|
458
467
|
removals (dedupe/error-purge/superseded-file-ops) structurally cannot beat
|
|
@@ -114,6 +114,22 @@ const DEFAULT_CACHED_PRICE_RATIO = 0.1;
|
|
|
114
114
|
*/
|
|
115
115
|
const DEFAULT_BREAK_EVEN_THRESHOLD = 22;
|
|
116
116
|
|
|
117
|
+
/**
|
|
118
|
+
* Default mid_loop break-even threshold (pe-zy4s follow-up). The package's own
|
|
119
|
+
* representative-corpus benchmark (turn-START state definition — the same one
|
|
120
|
+
* the runtime `context` handler uses) favored rejecting mid_loop candidates
|
|
121
|
+
* at cachedPriceRatio r=0.1 (mid_loop-optimal T=1, total realized
|
|
122
|
+
* net benefit ~0.0). This supports a conservative default for the measured
|
|
123
|
+
* corpus, not a universal claim that mid_loop pruning cannot pay off.
|
|
124
|
+
* The reported 2026-09-08 byte-level capture (a mid_loop prune at T=22
|
|
125
|
+
* invalidating 81% of a warm request prefix) illustrates cache invalidation,
|
|
126
|
+
* not an inability to amortize it: enough subsequent calls can recoup a
|
|
127
|
+
* one-time bust. Idle keeps T=22; turn-start classification does not imply
|
|
128
|
+
* the provider cache is cold. Users who want the old behavior can override
|
|
129
|
+
* via gate.breakEvenThresholdByState.mid_loop.
|
|
130
|
+
*/
|
|
131
|
+
const DEFAULT_MID_LOOP_BREAK_EVEN_THRESHOLD = 1;
|
|
132
|
+
|
|
117
133
|
/** Tool names never pruned by default: orchestration/subagent-style tools and todo-like state. */
|
|
118
134
|
const DEFAULT_PROTECTED_TOOL_NAMES = [
|
|
119
135
|
"todo",
|
|
@@ -222,20 +238,19 @@ export type GateMode = "on" | "off" | "always-apply";
|
|
|
222
238
|
* turn-START "idle" population (calls made at the start of a turn) carries
|
|
223
239
|
* essentially ALL the realized net benefit (idle-optimal T=22, total realized
|
|
224
240
|
* net benefit ~20,594 token-units), while "mid_loop" carries essentially NONE
|
|
225
|
-
* (mid_loop-optimal T=1, total realized net benefit ~0.0
|
|
226
|
-
* candidate is ever worth accepting at r=0.1 under this definition). This is
|
|
241
|
+
* (mid_loop-optimal T=1, total realized net benefit ~0.0 on this corpus). This is
|
|
227
242
|
* the OPPOSITE of what the pe-c5n9 evidence (measured under the old,
|
|
228
243
|
* non-runtime-observable turn-END definition) suggested.
|
|
229
244
|
*
|
|
230
245
|
* Per the pe-zy4s decision rule (stricter idle default only if idle itself is
|
|
231
246
|
* shown to be ~worthless): idle is NOT worthless here -- it is the ONLY state
|
|
232
|
-
* carrying value at r=0.1 -- so
|
|
233
|
-
*
|
|
234
|
-
* (
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
247
|
+
* carrying value at r=0.1 -- so the idle default stays at
|
|
248
|
+
* DEFAULT_BREAK_EVEN_THRESHOLD. The mid_loop default, by the same benchmark,
|
|
249
|
+
* is now DEFAULT_MID_LOOP_BREAK_EVEN_THRESHOLD (=1): the measured candidates
|
|
250
|
+
* did not justify a more permissive threshold at r=0.1. Mid_loop pruning can
|
|
251
|
+
* still amortize over enough subsequent calls; state alone does not establish
|
|
252
|
+
* cache warmth or profitability. Both defaults remain config-overridable via
|
|
253
|
+
* gate.breakEvenThresholdByState.
|
|
239
254
|
*/
|
|
240
255
|
export type AgentState = "idle" | "mid_loop";
|
|
241
256
|
|
|
@@ -285,7 +300,7 @@ export function defaultConfig(): DynamicContextPruningConfig {
|
|
|
285
300
|
mode: "on",
|
|
286
301
|
cachedPriceRatio: DEFAULT_CACHED_PRICE_RATIO,
|
|
287
302
|
breakEvenThreshold: DEFAULT_BREAK_EVEN_THRESHOLD,
|
|
288
|
-
breakEvenThresholdByState: { idle: DEFAULT_BREAK_EVEN_THRESHOLD, mid_loop:
|
|
303
|
+
breakEvenThresholdByState: { idle: DEFAULT_BREAK_EVEN_THRESHOLD, mid_loop: DEFAULT_MID_LOOP_BREAK_EVEN_THRESHOLD },
|
|
289
304
|
},
|
|
290
305
|
};
|
|
291
306
|
}
|
|
@@ -2410,7 +2425,7 @@ export function formatStatusReport(input: StatusReportInput): string[] {
|
|
|
2410
2425
|
const lines: string[] = [];
|
|
2411
2426
|
lines.push(`Dynamic context pruning: ${config.enabled ? "ENABLED" : "disabled"}`);
|
|
2412
2427
|
lines.push(
|
|
2413
|
-
`Gate: mode=${config.gate.mode}
|
|
2428
|
+
`Gate: mode=${config.gate.mode} thresholds={idle:${resolveBreakEvenThreshold(config.gate, "idle")}, mid_loop:${resolveBreakEvenThreshold(config.gate, "mid_loop")}} cachedPriceRatio=${config.gate.cachedPriceRatio}`,
|
|
2414
2429
|
);
|
|
2415
2430
|
lines.push("Strategies:");
|
|
2416
2431
|
lines.push(` dedupe: ${config.strategies.dedupe.enabled ? "on" : "off"}`);
|
|
@@ -230,21 +230,16 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
230
230
|
"claude-fable-5",
|
|
231
231
|
"claude-opus-4.8",
|
|
232
232
|
"claude-opus-4.7",
|
|
233
|
-
"
|
|
234
|
-
"claude-opus-4.5",
|
|
233
|
+
"gpt-6-astra",
|
|
235
234
|
"gpt-5.6-sol",
|
|
236
235
|
"gpt-5.6-terra",
|
|
237
236
|
"gpt-5.6-luna",
|
|
238
237
|
"gpt-5.5",
|
|
239
238
|
"gpt-5.4",
|
|
240
239
|
"gpt-5.3-codex",
|
|
241
|
-
"gpt-5.2-codex",
|
|
242
|
-
"gpt-5.2",
|
|
243
|
-
"gemini-3.1-pro-preview",
|
|
244
240
|
"gemini-3.5-flash",
|
|
245
241
|
"claude-sonnet-5",
|
|
246
242
|
"claude-sonnet-4.6",
|
|
247
|
-
"claude-sonnet-4.5",
|
|
248
243
|
"gpt-5-mini",
|
|
249
244
|
"kimi-k3",
|
|
250
245
|
"kimi-k2.7-code",
|
|
@@ -306,6 +301,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
306
301
|
"zai-glm-5-2",
|
|
307
302
|
],
|
|
308
303
|
openai: [
|
|
304
|
+
"gpt-6-astra",
|
|
309
305
|
"gpt-5.6-sol",
|
|
310
306
|
"gpt-5.6-terra",
|
|
311
307
|
"gpt-5.6-luna",
|
|
@@ -325,6 +321,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
325
321
|
"gpt-5-mini",
|
|
326
322
|
],
|
|
327
323
|
"openai-codex": [
|
|
324
|
+
"gpt-6-astra",
|
|
328
325
|
"gpt-5.6-sol",
|
|
329
326
|
"gpt-5.6-terra",
|
|
330
327
|
"gpt-5.6-luna",
|
|
@@ -383,9 +380,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
383
380
|
"anthropic/claude-fable-5",
|
|
384
381
|
"~anthropic/claude-fable-latest",
|
|
385
382
|
"anthropic/claude-opus-4.8",
|
|
386
|
-
"anthropic/claude-opus-4.8-fast",
|
|
387
383
|
"anthropic/claude-opus-4.7",
|
|
388
|
-
"anthropic/claude-opus-4.7-fast",
|
|
389
384
|
"anthropic/claude-opus-4.6",
|
|
390
385
|
"anthropic/claude-opus-4.5",
|
|
391
386
|
"anthropic/claude-opus-4.1",
|
|
@@ -511,7 +506,6 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
511
506
|
"grok-4.6",
|
|
512
507
|
"grok-4.5",
|
|
513
508
|
"grok-4.3",
|
|
514
|
-
"grok-build-0.1",
|
|
515
509
|
],
|
|
516
510
|
xiaomi: ["mimo-v2.5-pro-ultraspeed", "mimo-v2.5-pro", "mimo-v2.5"],
|
|
517
511
|
"xiaomi-token-plan-ams": ["mimo-v2.5-pro", "mimo-v2.5"],
|
|
@@ -524,9 +518,7 @@ const PROVIDER_MODEL_PREFERENCES: Record<string, string[]> = {
|
|
|
524
518
|
"deepseek-ai/deepseek-v4-pro-0813",
|
|
525
519
|
"moonshotai/kimi-k2.6",
|
|
526
520
|
"minimaxai/minimax-m3",
|
|
527
|
-
"openai/gpt-oss-120b",
|
|
528
521
|
"nvidia/nemotron-3-nano-omni-30b-a3b-reasoning",
|
|
529
|
-
"nvidia/nemotron-3-nano-30b-a3b",
|
|
530
522
|
],
|
|
531
523
|
zai: [
|
|
532
524
|
"glm-5.3",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diegopetrucci/pi-extensions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.68",
|
|
4
4
|
"description": "A collection of pi extensions and skills for annotation UIs, context management, workflow audits, contrarian review, review-comment triage, notifications, brrr push alerts, safety guards, GitHub research, repo-local knowledge, todos, tool rendering, model/provider helpers, and Xiaohei-style article illustrations.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -71,9 +71,9 @@
|
|
|
71
71
|
]
|
|
72
72
|
},
|
|
73
73
|
"devDependencies": {
|
|
74
|
-
"@earendil-works/pi-ai": "^0.
|
|
75
|
-
"@earendil-works/pi-coding-agent": "^0.
|
|
76
|
-
"@earendil-works/pi-tui": "^0.
|
|
74
|
+
"@earendil-works/pi-ai": "^0.85.1",
|
|
75
|
+
"@earendil-works/pi-coding-agent": "^0.85.1",
|
|
76
|
+
"@earendil-works/pi-tui": "^0.85.1",
|
|
77
77
|
"@types/node": "^25.9.1",
|
|
78
78
|
"husky": "^9.1.7",
|
|
79
79
|
"typebox": "^1.3.6",
|