pi-plus 0.1.11 → 0.1.12
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 +17 -0
- package/README.md +15 -4
- package/package.json +1 -1
- package/pipi.js +259 -200
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- A `<tasks>` system-prompt section (registered by the `pi-plus-tasks` extension on every agent start) nudging the model to break non-trivial multi-step work into TaskCreate tasks and update statuses as it goes, and listing the session's current tasks (with status and blockers) when non-empty so resumed sessions can pick up where they left off.
|
|
8
|
+
- A `<subagents>` system-prompt section (registered by the `pi-plus-subagent` extension on every agent start) nudging the model to delegate self-contained work units via the `subagent` tool — including complete, self-contained prompts and concurrent calls in one turn — and listing the agent types available in this session (built-in `worker`/`explore` plus user- and project-defined agents) with their source, tools, and model.
|
|
9
|
+
- `PI_AUTOCOMPACT_FAILURE_COOLDOWN_MS` env override (minimum 10s, values below the floor fall back to the 5-minute default) for the auto-compact circuit breaker: after 3 consecutive failures the breaker now cools down instead of latching forever — one attempt is allowed through once the cooldown elapses (half-open), and a failed attempt re-trips it.
|
|
10
|
+
- Layered context defense (pi-plus-context-guard extension + AgentSession constructor hook, ported from openclaude): a message-count force trigger compacts when the active message count exceeds `PI_MAX_ACTIVE_MESSAGES` (default 1000) regardless of the token threshold; relevance pruning omits low-relevance old text entries via durable `context_edit` overlays once the projected request reaches the auto-compact threshold, protecting the recent `PI_PRUNE_TAIL_TURNS` (default 3) turns, tool interactions, errors, and prior compaction summaries; time-based micro-compact clears the content of stale tool results (`PI_MICROCOMPACT_IDLE_MINUTES`, default 60; keeps the newest `PI_MICROCOMPACT_KEEP_RECENT`, default 5) when a session is opened after an idle gap, since the server prompt cache is dead anyway; and resuming a session already at ≥ 70% of the auto-compact threshold offers a "Compact now?" confirmation in the TUI.
|
|
11
|
+
- Post-compact re-injection of the active plan file and invoked skills into the compaction summary (openclaude's `createPlanAttachmentIfNeeded` / `createSkillAttachmentIfNeeded`), alongside the existing recent-files re-injection.
|
|
12
|
+
- Recompaction analytics (openclaude's `RecompactionInfo`) persisted in the compaction entry's `details`: whether the compaction continues a chain, turns consumed since the previous compaction, the previous pre-compact token count, and a `willRetriggerNextTurn` prediction; set `PI_COMPACT_ANALYTICS` for a stderr diagnostic line.
|
|
13
|
+
- `/settings` gains an "Auto-compact threshold" row (70%/80%/85%/90%/95%, default 80%), injected into the settings selector by the plus wrapper. The choice persists to `~/.pi/agent/pi-plus-settings.json` and applies as a percent of the effective context window, replacing the CC buffer math as the user-facing default — unlike `PI_AUTOCOMPACT_PCT_OVERRIDE`, which stays a session-scoped test knob capped at the CC buffer.
|
|
14
|
+
- `/settings` gains a "Context floor" row (13000–65536 tokens, default 13000) for the floor under the effective context window: the window used for auto-compact math never drops below the output reserve plus this many tokens, even for small-context models. The choice persists to `~/.pi/agent/pi-plus-settings.json` and can only raise the built-in 13k floor (the issue-#635 guarantee stays intact); `PI_CONTEXT_FLOOR_TOKENS` overrides it for the session.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- The window used for threshold math is now ceilinged at 256K tokens (`AUTOCOMPACT_MAX_WINDOW_TOKENS`) before the output reservation: models advertising windows far beyond practical agentic session sizes (e.g. the 1M-token DeepSeek V4.1 Flash) previously got an ~800K auto-compact threshold that effectively never fired, letting the transcript grow unbounded. A 1M model now triggers at ~194K (80% of the 242K effective window). `PI_AUTO_COMPACT_WINDOW` keeps its cap semantics and can only lower this further. The footer's context fullness percentage uses the same effective window as its denominator when the ceiling engages, so the meter reads "percent of the usable window" (e.g. `14.4%/242K`) instead of crawling against the unreachable 1M capacity; models at or below the ceiling are unchanged.
|
|
19
|
+
|
|
20
|
+
- The CC buffer math (ramped 13k–30k by effective window size, openclaude issue #1949; floored effective window for small-context models, issue #635) no longer sets the auto-compact threshold directly — it survives only as the cap for the `PI_AUTOCOMPACT_PCT_OVERRIDE` test knob. The user-facing threshold is now a percent of the effective window chosen in `/settings` (default 80%). `percentLeft` is computed against the raw context window so the displayed percentage reflects full model capacity.
|
|
21
|
+
|
|
5
22
|
### Fixed
|
|
6
23
|
|
|
7
24
|
- `pipi remove`/`pipi install` under a profile now update the source `~/.pi/agent/settings.json` `packages` list, not just the per-profile copy that the next materialization would discard. The wrapper registers a process-exit sync (`syncProfilePackagesToSource` from pi-hub) for profile launches, so the removed extension is not reinstalled on next launch.
|
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@ All override/custom logic lives here. Direct updates to any other folder under `
|
|
|
6
6
|
|
|
7
7
|
Ports Claude Code semantics (reference: `../free-code/`, CC v2.1.87) onto pi's context detection, compaction, and reasoning — with pi-style env var names:
|
|
8
8
|
|
|
9
|
-
1. **Context usage detection** (`src/context/detection.ts`) — effective context window = `contextWindow − min(maxTokens, 20000)
|
|
9
|
+
1. **Context usage detection** (`src/context/detection.ts`) — effective context window = `min(contextWindow, 256K) − min(maxTokens, 20000)`, so 1M-context models (e.g. DeepSeek V4.1 Flash) get a sane ~190K auto-compact threshold instead of ~800K that never fires; auto-compact threshold = a percent of the effective window (**default 80%**, adjustable 70–95% in `/settings`); warning/error = threshold ∓ 20k; blocking limit = effective window − 3k; 3-failure circuit breaker. When the 256K ceiling engages, the footer's fullness percentage is also measured against the effective window (e.g. `14.4%/242K`), so the meter tracks the usable window instead of crawling against raw 1M capacity. The "Auto-compact threshold" row persists to `~/.pi/agent/pi-plus-settings.json` (`src/context/threshold-setting.ts`); `PI_AUTOCOMPACT_PCT_OVERRIDE` keeps its session-scoped, capped-at-the-CC-buffer test semantics. The effective window is also floored at the output reserve plus a context floor buffer (**default 13k**, adjustable 13000–65536 in `/settings`); the floor only ever raises the built-in 13k minimum so small-context models keep a usable (non-negative-threshold) window, and `PI_CONTEXT_FLOOR_TOKENS` overrides it for the session.
|
|
10
10
|
2. **Compaction** (`src/compaction/`) — single full-conversation summary using the CC 9-section prompt (`prompt.ts`); prompt-too-long retries drop the oldest turn (`compact.ts`); post-compact re-injection of up to 5 recently read files (50k token budget).
|
|
11
11
|
3. **Reasoning effort** (`src/reasoning/effort.ts`) — CC effort levels (`low`/`medium`/`high`/`max`, `max` → `xhigh` → `high` downgrading), adaptive thinking default, `ultrathink` keyword → high effort for that turn, thinking budgets from env.
|
|
12
12
|
4. **Hub profiles** (`src/coding-agent/main.ts` wrapper, backed by `@earendil-works/pi-hub` = `packages/hub`) — named pi profiles (provider/models/thinking/token/base URL) stored in `~/.pi/profiles.json`, materialized into isolated agent dirs under `~/.pi/pi-hub/profiles/<name>/`. Adds `pipi profile …`, `pipi use` / `pipi unuse`, and the `pipi --as <name>` flag. The wrapper resolves the profile, sets `PI_CODING_AGENT_DIR` in-process (read lazily by `getAgentDir()`), and delegates to the original `main`.
|
|
@@ -17,15 +17,18 @@ Ports Claude Code semantics (reference: `../free-code/`, CC v2.1.87) onto pi's c
|
|
|
17
17
|
9. **Task tools** (`src/extensions/tasks/`, openclaude V2 style) — `TaskCreate`/`TaskUpdate`/`TaskList`/`TaskGet` backed by one JSON file per task under `<agent dir>/tasks/<sessionId>/` (monotonic ids via `.highwatermark`, atomic tmp+rename writes), with per-task `owner` and `blocks`/`blockedBy` dependencies. `/tasks` or `ctrl+shift+t` opens a task-list overlay in the TUI.
|
|
18
18
|
10. **ask_user tool** (`src/extensions/ask-user/`, openclaude AskUserQuestion style) — the model can ask 1–4 structured questions per call (2–4 options with descriptions each, optional `multiSelect`, automatic "Other" free-text). In TUI mode a tabbed overlay dialog collects the answers; RPC mode falls back to sequential select/input dialogs; print/JSON mode makes the tool fail with an error result so the model proceeds with its own assumptions. Guardrails: unique question texts and option labels, no model-supplied "Other" option, header chips ≤ 12 chars.
|
|
19
19
|
11. **User command hooks** (`src/extensions/hooks/`) — fires command hooks declared in `settings.json` under a `"hooks"` key (per-event matcher groups of `{type:"command", command, async}` entries; hooks from `~/.pi`, the agent dir, and the project `.pi` settings files are merged) at CC-analogue moments: `PermissionRequest` when any blocking prompt opens (ask_user dialog, plan-mode entry/approval), `PreToolUse` per tool call (`ask_user` matches `AskUserQuestion` matchers), `Stop` when the agent settles. Fire-and-forget detached spawns; never blocks or fails the agent.
|
|
20
|
+
12. **Long-term memory** (`src/extensions/memory/`, openclaude memdir/extractMemories style) — per-project memories as markdown files with frontmatter (`name`, `description`, `type`: user/feedback/project/reference) under `<agent dir>/memory/<project-key>/`, indexed in `MEMORY.md` (200-line / 25 KB caps). The `memory_save`/`memory_recall` tools let the model persist and search durable facts; the index is injected as a `<memory>` system-prompt section each run; `/memory` browses/edits/adds/forgets. At `agent_settled` a background sub-agent restricted to the two memory tools reviews the conversation and saves noteworthy facts (skipped when the main agent already saved one, below `extractMinMessages` new messages, or within `extractCooldownMs`). Toggle via the `"memory"` key in settings.json (`enabled`, `autoExtract`, `extractMinMessages`, `extractCooldownMs`; project > agent dir > `~/.pi`).
|
|
21
|
+
13. **Tab title + busy spinner** (`src/extensions/tab-title/`) — the terminal window/tab title brands as `pi+ - [sessionName -] cwdBasename` (via the `config.ts` wrapper's `APP_TITLE`, which upstream's `updateTerminalTitle` also uses, so both paths agree). While the agent is working (`agent_start` until `agent_settled`/`turn_end`), a braille spinner frame is prepended to the title and ticks every 120 ms, so a backgrounded tab shows at a glance that pi+ is busy. TUI mode only; the ticker is cleared on session shutdown.
|
|
22
|
+
14. **Plain tool blocks** (`src/extensions/plain-tools/`) — strips the background fills upstream paints on tool result blocks (`toolPendingBg` while running, `toolSuccessBg`/`toolErrorBg` on completion, including edit diff boxes), so tool status reads as text — words like `Command exited with code 3` and the subagent tool's `running` / `✓ done` / `✗ failed` — instead of colored blocks. Implemented as a one-time `Theme.prototype.bg` wrapper (idempotent, applied at extension registration), so it holds across theme switches and spares every other background token (selections, user message bubble).
|
|
20
23
|
|
|
21
|
-
The CLI identifies as **`pipi`** (pi-plus) via the `config.ts` wrapper
|
|
24
|
+
The CLI identifies as **`pipi`** (pi-plus) in CLI text via the `config.ts` wrapper's `APP_NAME` shadow; the terminal tab title brands as **`pi+`** via the `APP_TITLE` shadow. Scope is the display name only — config dir (`.pi`), `PI_`-prefixed env vars, and session layout stay pi's.
|
|
22
25
|
|
|
23
26
|
## Mechanism
|
|
24
27
|
|
|
25
28
|
- `loader/hooks.mjs` — Node module customization hook. Two jobs: (a) map `@earendil-works/*` specifiers to `packages/*/src` (mirrors root tsconfig paths), (b) redirect selected upstream modules to the wrapper modules below. Importers inside `packages/plus/` are never redirected, so wrappers can import the true original via relative path without a loop.
|
|
26
29
|
- `loader/run-plus.mjs` + `pipi` — entry point. Runs pi from TypeScript sources on Node's native type stripping (the repo is `erasableSyntaxOnly`). tsx is intentionally not used: its load hook silently produces empty modules when another customization hook is registered alongside it (Node 25).
|
|
27
30
|
- `src/<upstream-path>.ts` — wrapper modules. Each does `export * from "<relative path to original>"` and redefines selected exports; per ESM spec, explicit named exports shadow star exports, so everything not overridden passes through untouched.
|
|
28
|
-
- Redirect map: `loader/redirects.mjs` (
|
|
31
|
+
- Redirect map: `loader/redirects.mjs` (10 modules: coding-agent compaction/agent-session/model-resolver/defaults/config/main/cli-args/settings-selector, agent agent.ts, agent harness compaction).
|
|
29
32
|
|
|
30
33
|
## Shell completion
|
|
31
34
|
|
|
@@ -43,11 +46,19 @@ source <(pipi completion bash) # add to ~/.bashrc
|
|
|
43
46
|
| Var | Values | Effect |
|
|
44
47
|
| ----------------------------- | ----------------------------------- | --------------------------------------------------------------- |
|
|
45
48
|
| `PI_MAX_CONTEXT_TOKENS` | number | Overrides `model.contextWindow` after model resolution |
|
|
46
|
-
| `PI_AUTO_COMPACT_WINDOW` | number | Caps the window used for threshold math
|
|
49
|
+
| `PI_AUTO_COMPACT_WINDOW` | number | Caps the window used for threshold math (cannot raise the 256K ceiling) |
|
|
47
50
|
| `PI_AUTOCOMPACT_PCT_OVERRIDE` | 1–100 | Auto-compact threshold as % of effective window (capped at default) |
|
|
51
|
+
| `PI_CONTEXT_FLOOR_TOKENS` | number ≥ 13000 | Context floor override (only raises the built-in 13k floor) |
|
|
48
52
|
| `PI_BLOCKING_LIMIT_OVERRIDE` | number | Blocking limit override |
|
|
49
53
|
| `PI_DISABLE_COMPACT` | truthy | Disables all compaction (incl. manual) |
|
|
50
54
|
| `PI_DISABLE_AUTO_COMPACT` | truthy | Disables threshold-triggered auto-compaction |
|
|
55
|
+
| `PI_AUTOCOMPACT_FAILURE_COOLDOWN_MS` | ms ≥ 10000 | Circuit-breaker cooldown after 3 consecutive auto-compact failures |
|
|
56
|
+
| `PI_MAX_ACTIVE_MESSAGES` | number (`0`/invalid = off, default 1000) | Forces compaction when the active message count exceeds the cap |
|
|
57
|
+
| `PI_PRUNE_TAIL_TURNS` | number ≥ 1 (default 3) | Recent turns preserved verbatim by relevance pruning |
|
|
58
|
+
| `PI_MICROCOMPACT_IDLE_MINUTES` | minutes (default 60; ≤ 0 disables) | Idle gap that triggers clearing of stale tool-result content on session open |
|
|
59
|
+
| `PI_MICROCOMPACT_KEEP_RECENT` | number (default 5) | Tool results preserved verbatim by idle micro-compact |
|
|
60
|
+
| `PI_COMPACT_ANALYTICS` | truthy | Emits recompaction diagnostics to stderr after compaction |
|
|
61
|
+
| `PI_PLUS_SETTINGS_FILE` | path | Overrides `~/.pi/agent/pi-plus-settings.json` (test/debug knob) |
|
|
51
62
|
| `PI_EFFORT_LEVEL` | `off`/`auto`/`low`/`medium`/`high`/`max` | Per-request reasoning effort override |
|
|
52
63
|
| `PI_MAX_THINKING_TOKENS` | number (`0` disables) | Thinking budget (enables thinking at `high` when > 0) |
|
|
53
64
|
| `PI_DISABLE_THINKING` | truthy | Disables thinking entirely |
|