pi-ghost-autocomplete 0.3.1 → 0.3.2
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/README.md +101 -6
- package/dist/bench-cli.js +81 -5
- package/dist/bench-cli.js.map +1 -1
- package/dist/bench.d.ts +130 -2
- package/dist/bench.d.ts.map +1 -1
- package/dist/bench.js +285 -4
- package/dist/bench.js.map +1 -1
- package/dist/cache.d.ts +124 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +173 -0
- package/dist/cache.js.map +1 -0
- package/dist/candidate-rerank.d.ts +57 -0
- package/dist/candidate-rerank.d.ts.map +1 -0
- package/dist/candidate-rerank.js +78 -0
- package/dist/candidate-rerank.js.map +1 -0
- package/dist/config.d.ts +43 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +148 -18
- package/dist/config.js.map +1 -1
- package/dist/context-aggregator.d.ts +14 -5
- package/dist/context-aggregator.d.ts.map +1 -1
- package/dist/context-aggregator.js +38 -9
- package/dist/context-aggregator.js.map +1 -1
- package/dist/context-selector.d.ts +128 -0
- package/dist/context-selector.d.ts.map +1 -0
- package/dist/context-selector.js +300 -0
- package/dist/context-selector.js.map +1 -0
- package/dist/cycle-manager.d.ts +102 -0
- package/dist/cycle-manager.d.ts.map +1 -0
- package/dist/cycle-manager.js +168 -0
- package/dist/cycle-manager.js.map +1 -0
- package/dist/edit-history-ring.d.ts +148 -0
- package/dist/edit-history-ring.d.ts.map +1 -0
- package/dist/edit-history-ring.js +262 -0
- package/dist/edit-history-ring.js.map +1 -0
- package/dist/entropy-stop.d.ts +102 -0
- package/dist/entropy-stop.d.ts.map +1 -0
- package/dist/entropy-stop.js +141 -0
- package/dist/entropy-stop.js.map +1 -0
- package/dist/eval-dataset.d.ts +66 -0
- package/dist/eval-dataset.d.ts.map +1 -0
- package/dist/eval-dataset.js +127 -0
- package/dist/eval-dataset.js.map +1 -0
- package/dist/fast-path-engine.d.ts +286 -0
- package/dist/fast-path-engine.d.ts.map +1 -0
- package/dist/fast-path-engine.js +341 -0
- package/dist/fast-path-engine.js.map +1 -0
- package/dist/fuzzy-matcher.d.ts +8 -0
- package/dist/fuzzy-matcher.d.ts.map +1 -1
- package/dist/fuzzy-matcher.js +5 -3
- package/dist/fuzzy-matcher.js.map +1 -1
- package/dist/ghost-editor.d.ts +321 -4
- package/dist/ghost-editor.d.ts.map +1 -1
- package/dist/ghost-editor.js +1190 -144
- package/dist/ghost-editor.js.map +1 -1
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +81 -2
- package/dist/index.js.map +1 -1
- package/dist/keystroke-timer.d.ts +59 -0
- package/dist/keystroke-timer.d.ts.map +1 -0
- package/dist/keystroke-timer.js +94 -0
- package/dist/keystroke-timer.js.map +1 -0
- package/dist/metrics-builder.d.ts +71 -0
- package/dist/metrics-builder.d.ts.map +1 -0
- package/dist/metrics-builder.js +71 -0
- package/dist/metrics-builder.js.map +1 -0
- package/dist/metrics.d.ts +99 -2
- package/dist/metrics.d.ts.map +1 -1
- package/dist/metrics.js +131 -17
- package/dist/metrics.js.map +1 -1
- package/dist/path-matcher.d.ts +9 -0
- package/dist/path-matcher.d.ts.map +1 -1
- package/dist/path-matcher.js +5 -2
- package/dist/path-matcher.js.map +1 -1
- package/dist/profile-store.d.ts +82 -0
- package/dist/profile-store.d.ts.map +1 -0
- package/dist/profile-store.js +199 -0
- package/dist/profile-store.js.map +1 -0
- package/dist/profile.d.ts +185 -0
- package/dist/profile.d.ts.map +1 -0
- package/dist/profile.js +434 -0
- package/dist/profile.js.map +1 -0
- package/dist/providers/cloud-provider.d.ts +10 -1
- package/dist/providers/cloud-provider.d.ts.map +1 -1
- package/dist/providers/cloud-provider.js +71 -14
- package/dist/providers/cloud-provider.js.map +1 -1
- package/dist/providers/local-provider.d.ts +8 -1
- package/dist/providers/local-provider.d.ts.map +1 -1
- package/dist/providers/local-provider.js +15 -3
- package/dist/providers/local-provider.js.map +1 -1
- package/dist/providers/openai-compat-provider.d.ts +11 -1
- package/dist/providers/openai-compat-provider.d.ts.map +1 -1
- package/dist/providers/openai-compat-provider.js +93 -6
- package/dist/providers/openai-compat-provider.js.map +1 -1
- package/dist/providers/openai-completions-runner.d.ts +25 -1
- package/dist/providers/openai-completions-runner.d.ts.map +1 -1
- package/dist/providers/openai-completions-runner.js +109 -14
- package/dist/providers/openai-completions-runner.js.map +1 -1
- package/dist/providers/race.d.ts +58 -1
- package/dist/providers/race.d.ts.map +1 -1
- package/dist/providers/race.js +317 -4
- package/dist/providers/race.js.map +1 -1
- package/dist/providers/truncate.d.ts.map +1 -1
- package/dist/providers/truncate.js +20 -2
- package/dist/providers/truncate.js.map +1 -1
- package/dist/providers/types.d.ts +96 -1
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/providers/types.js +59 -1
- package/dist/providers/types.js.map +1 -1
- package/dist/provisional-manager.d.ts +93 -0
- package/dist/provisional-manager.d.ts.map +1 -0
- package/dist/provisional-manager.js +98 -0
- package/dist/provisional-manager.js.map +1 -0
- package/dist/provisional.d.ts +150 -0
- package/dist/provisional.d.ts.map +1 -0
- package/dist/provisional.js +238 -0
- package/dist/provisional.js.map +1 -0
- package/dist/regret-tracker.d.ts +84 -0
- package/dist/regret-tracker.d.ts.map +1 -0
- package/dist/regret-tracker.js +145 -0
- package/dist/regret-tracker.js.map +1 -0
- package/dist/replay-cli.d.ts +13 -0
- package/dist/replay-cli.d.ts.map +1 -0
- package/dist/replay-cli.js +167 -0
- package/dist/replay-cli.js.map +1 -0
- package/dist/replay.d.ts +107 -0
- package/dist/replay.d.ts.map +1 -0
- package/dist/replay.js +225 -0
- package/dist/replay.js.map +1 -0
- package/dist/reranker.d.ts +181 -0
- package/dist/reranker.d.ts.map +1 -0
- package/dist/reranker.js +324 -0
- package/dist/reranker.js.map +1 -0
- package/dist/session-trie.d.ts +103 -0
- package/dist/session-trie.d.ts.map +1 -0
- package/dist/session-trie.js +280 -0
- package/dist/session-trie.js.map +1 -0
- package/dist/speculative.d.ts +74 -0
- package/dist/speculative.d.ts.map +1 -0
- package/dist/speculative.js +107 -0
- package/dist/speculative.js.map +1 -0
- package/dist/tool-summarize.d.ts +40 -0
- package/dist/tool-summarize.d.ts.map +1 -0
- package/dist/tool-summarize.js +245 -0
- package/dist/tool-summarize.js.map +1 -0
- package/dist/trie-sanitize.d.ts +22 -0
- package/dist/trie-sanitize.d.ts.map +1 -0
- package/dist/trie-sanitize.js +142 -0
- package/dist/trie-sanitize.js.map +1 -0
- package/dist/versions.d.ts +23 -0
- package/dist/versions.d.ts.map +1 -0
- package/dist/versions.js +31 -0
- package/dist/versions.js.map +1 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -14,8 +14,8 @@ Four provider modes ship in the same package:
|
|
|
14
14
|
| --- | --- | --- | --- |
|
|
15
15
|
| `cloud` | Groq / Cerebras / OpenRouter via `@earendil-works/pi-ai` | 150 ms | `groq/llama-3.1-8b-instant` |
|
|
16
16
|
| `local` | Ollama / vLLM (OpenAI-compatible) | 400 ms | `qwen2.5-coder:1.5b` on `http://localhost:11434` |
|
|
17
|
-
| `openai-compat` | Any OpenAI-compatible REST API (e.g. Mercury Edit) —
|
|
18
|
-
| `race` | Multiple providers in parallel; first valid response wins |
|
|
17
|
+
| `openai-compat` | Any OpenAI-compatible REST API (e.g. Mercury Edit) — also used as the **default** provider | 150 ms | `mercury-edit-2` on `https://api.inceptionlabs.ai/v1` |
|
|
18
|
+
| `race` | Multiple providers in parallel; first valid response wins | 400 ms | per-member defaults |
|
|
19
19
|
|
|
20
20
|
## Getting started
|
|
21
21
|
|
|
@@ -70,7 +70,17 @@ Start typing at the prompt. A dim ghost text should appear to the right of your
|
|
|
70
70
|
Run `/ghost` to confirm the extension loaded and see the active configuration:
|
|
71
71
|
|
|
72
72
|
```
|
|
73
|
-
Pi Ghost: enabled
|
|
73
|
+
Pi Ghost: enabled
|
|
74
|
+
minChars=3
|
|
75
|
+
maxLineLength=240
|
|
76
|
+
mode=openai-compat
|
|
77
|
+
provider=mercury-edit
|
|
78
|
+
baseUrl=https://api.inceptionlabs.ai/v1
|
|
79
|
+
model=mercury-edit-2
|
|
80
|
+
apiKey=4e24***
|
|
81
|
+
debounceMs=150
|
|
82
|
+
maxTokens=64
|
|
83
|
+
maxRecentMessages=4
|
|
74
84
|
```
|
|
75
85
|
|
|
76
86
|
### 4. (Optional) Load the extension without installing
|
|
@@ -104,9 +114,37 @@ All knobs are environment variables — no extra config file needed:
|
|
|
104
114
|
| `PI_GHOST_RECENT` | 4 (cloud) / 2 (local) | Number of recent user/assistant messages bundled as context |
|
|
105
115
|
| `PI_GHOST_MIN_CHARS` | 3 | Minimum draft length before a prediction fires |
|
|
106
116
|
| `PI_GHOST_MAX_LINE` | 240 | Predictions skipped if the current line exceeds this length |
|
|
117
|
+
| `PI_GHOST_TEMPERATURE` | `0` | Sampling temperature [0, 2]. `0` is best-effort deterministic; see note below |
|
|
118
|
+
| `PI_GHOST_MERCURY_PARALLEL_N` | `1` | Mercury FIM only: fire N parallel candidate completions for cycling. Requires `PI_GHOST_TEMPERATURE > 0` (downgrades silently to 1 at temp=0). Costs scale linearly with N |
|
|
119
|
+
| `PI_GHOST_CONTEXT_MAX_SCAN` | `200` | M6b: cap on the candidate pool scanned for relevance ranking |
|
|
120
|
+
| `PI_GHOST_CONTEXT_MAX_SELECTED` | `8` | M6b: max number of selected context entries |
|
|
121
|
+
| `PI_GHOST_CONTEXT_MAX_CHARS` | `4000` | M6b: total char budget for the selected context window |
|
|
122
|
+
| `PI_GHOST_CONTEXT_BM25_WEIGHT` | `0.3` | M6b: weight of BM25 content score vs recency (0=pure recency, 1=pure relevance) |
|
|
123
|
+
| `PI_GHOST_CONTEXT_TOOL_MAX` | `3` | M6c: max number of tool entries to include in selected context (0 disables tools entirely) |
|
|
124
|
+
| `PI_GHOST_ALLOW_INSECURE` | unset | Set to `1` to allow `http://` provider base URLs on non-localhost hosts. Off by default — API keys + prompts would be sent in clear |
|
|
125
|
+
| `PI_GHOST_PROFILE` | unset | Set to `off` to disable persistent profile capture + reranking. Default: enabled. Profile is local-only — see [Profile](#user-profile) below |
|
|
126
|
+
| `PI_GHOST_PROFILE_DECAY_DAYS` | `90` | Days before an unused profile record's weight halves during compaction |
|
|
127
|
+
| `PI_GHOST_PROVISIONAL` | unset | Set to `off` to disable the 150 ms provisional fallback. Default: enabled |
|
|
128
|
+
| `PI_GHOST_PROVISIONAL_PREFER` | unset | Set to `1`/`true`/`on`/`yes` to bias swap decisions toward the already-displayed provisional. Raises the LLM-vs-provisional swap margin from 0.1 to 0.3, reducing perceived flicker at the cost of recall. Bench reports a `flicker=X%` rate so this knob can be evaluated |
|
|
129
|
+
| `PI_GHOST_MIN_CONFIDENCE` | `0.55` | M3c.1: minimum reranker score for the top candidate to be shown. Range `[0, 1]`. Lower = more lenient, more ghosts shown |
|
|
130
|
+
| `PI_GHOST_RERANK_WEIGHTS` | `0.45,0.25,0.15,0.15` | M3c: reranker weights as `logprob,profileBias,lengthPrior,agreement`. Negative values clamped to 0 |
|
|
131
|
+
| `PI_GHOST_EVAL_CAPTURE` | unset | Set to `1` to capture committed prompts to `.pi/ghost-autocomplete/eval.jsonl` for offline replay (`pi-ghost-replay`). **Sensitive**: contains raw prompt text. Off by default |
|
|
132
|
+
| `PI_GHOST_REGRET_WINDOW_MS` | `3000` | After accept, window in ms during which a >50% deletion of inserted text flags the record `acceptRegret: true` |
|
|
133
|
+
| `PI_GHOST_SHORT_HOVER_MS` | `800` | Enhancement #3: a ghost dismissed within this many ms is flagged `shortHoverDismiss: true` and triggers a soft trie penalty (magnitude 0.25). Tunes the bench `short-hover` rate |
|
|
107
134
|
| `PI_GHOST_METRICS` | unset | Set to `1` to write metrics to `.pi/ghost-autocomplete/metrics.jsonl` |
|
|
108
135
|
| `PI_GHOST_DEBUG_LOG` | unset | Set to `1` to write debug records to `.pi/ghost-autocomplete/debug.jsonl` |
|
|
109
136
|
|
|
137
|
+
### Note on `temperature=0`
|
|
138
|
+
|
|
139
|
+
`temperature=0` is the default and asks the provider for greedy decoding so
|
|
140
|
+
the same prefix produces the same completion. This is **best-effort, not
|
|
141
|
+
guaranteed**: vendors batch requests across users and kernel scheduling
|
|
142
|
+
differences can produce different greedy paths from one call to the next.
|
|
143
|
+
The session's in-memory completion cache is the real determinism guarantee
|
|
144
|
+
— retyping the same prefix in the same context will reuse the previous
|
|
145
|
+
ghost rather than re-querying. Raise temperature only if you want
|
|
146
|
+
cache-miss diversity (e.g. `PI_GHOST_TEMPERATURE=0.5`).
|
|
147
|
+
|
|
110
148
|
Run `/ghost` inside Pi to see the effective config; `/ghost on` and
|
|
111
149
|
`/ghost off` toggle the feature for the current session.
|
|
112
150
|
|
|
@@ -159,6 +197,41 @@ shown, and acceptance outcome (`accepted`, `dismissed`, `stale`, `expired`).
|
|
|
159
197
|
Raw prompt text and LLM output are never written to the metrics file. Both
|
|
160
198
|
files rotate at 10 MB.
|
|
161
199
|
|
|
200
|
+
## User profile
|
|
201
|
+
|
|
202
|
+
The extension keeps a long-lived JSONL store at
|
|
203
|
+
`.pi/ghost-autocomplete/profile.jsonl` to learn slash-command, path, and
|
|
204
|
+
trigram frequencies across sessions. The profile feeds three local-only
|
|
205
|
+
signals:
|
|
206
|
+
|
|
207
|
+
1. **Slash fast-path.** When the active line starts with `/`, the editor
|
|
208
|
+
serves the most-typed extension as a ghost before the LLM is queried
|
|
209
|
+
(mode `trie`, provider `profile-slash`). Press Right to accept.
|
|
210
|
+
2. **Profile-bias rerank (M3c hook).** A `profileBias` score plugs into
|
|
211
|
+
the multi-candidate reranker. Wired but only takes effect when the
|
|
212
|
+
provider returns >1 candidate.
|
|
213
|
+
3. **Bounded path boost.** Persistent path frequency adds a small
|
|
214
|
+
capped boost to deterministic path/fuzzy ranking, capped so it cannot
|
|
215
|
+
beat a fresh exact path-prefix match.
|
|
216
|
+
|
|
217
|
+
What's stored: paths (`src/foo.ts`), slash commands (`/review`),
|
|
218
|
+
trigrams from committed prompts, and acceptance records keyed by the
|
|
219
|
+
SHA-256 hash of the prefix. Raw prefixes and raw completions are
|
|
220
|
+
**never** written. Token tuples are tokenized and capped at 4 for
|
|
221
|
+
prefix tails / 8 for completions.
|
|
222
|
+
|
|
223
|
+
Sanitization runs before persistence: messages with API keys (`sk-…`,
|
|
224
|
+
`ghp_…`, JWT, etc.) or high-entropy tokens (Shannon > 4.0 bits/char,
|
|
225
|
+
length ≥ 20) are dropped entirely. The check is shared with the session
|
|
226
|
+
trie (`src/trie-sanitize.ts`).
|
|
227
|
+
|
|
228
|
+
Rotation: when the JSONL exceeds 2 MB, the store compacts in place —
|
|
229
|
+
sums weights per `(kind, key)`, halves records older than 90 days
|
|
230
|
+
(configurable via `PI_GHOST_PROFILE_DECAY_DAYS`), drops weights below
|
|
231
|
+
0.1. The original file is preserved as `profile.jsonl.1`.
|
|
232
|
+
|
|
233
|
+
Set `PI_GHOST_PROFILE=off` to disable capture + use entirely.
|
|
234
|
+
|
|
162
235
|
## Benchmark CLI
|
|
163
236
|
|
|
164
237
|
The `pi-ghost-bench` binary reads a metrics JSONL file and reports p50/p95
|
|
@@ -186,11 +259,22 @@ Exit code is `0` when all thresholds pass, `1` when any fail, `2` on I/O error o
|
|
|
186
259
|
- The path index is built asynchronously at session start via `git ls-files`
|
|
187
260
|
from the repository root, capped at 20 000 files. High-confidence
|
|
188
261
|
basename-prefix matches (score ≥85) preempt the LLM unconditionally; lower-
|
|
189
|
-
confidence fuzzy matches only activate when an action word (open
|
|
190
|
-
read
|
|
262
|
+
confidence fuzzy matches only activate when an action word (`open`, `edit`,
|
|
263
|
+
`read`, `show`, `view`, `find`, `check`, `look`, `load`, `import`, `include`,
|
|
264
|
+
`see`, `run`) precedes the token.
|
|
191
265
|
- Recent agent messages come from `ctx.sessionManager.getBranch()` — only
|
|
192
266
|
user/assistant text, no tool calls. Both providers truncate to a small,
|
|
193
267
|
fixed payload so cloud requests don't ship the whole file.
|
|
268
|
+
- Path mentions are extracted from recent conversation messages (slashed
|
|
269
|
+
paths, backticked path-like tokens, and bare filenames with known code
|
|
270
|
+
extensions). These give a ranking boost (+10 exact, +7 basename) to
|
|
271
|
+
deterministic path completions, so recently discussed files surface
|
|
272
|
+
higher.
|
|
273
|
+
- For fuzzy filename matches where the typed token is not a prefix of the
|
|
274
|
+
match, the editor enters **replace mode**: accepting the ghost replaces
|
|
275
|
+
the typed token with the full matched path. A `→ ` prefix is rendered
|
|
276
|
+
before the ghost text to signal this behaviour. Prefix-suffix matches
|
|
277
|
+
still append as usual.
|
|
194
278
|
- `render()` searches for `CURSOR_MARKER` in the lines returned by
|
|
195
279
|
`super.render()` and injects ANSI dim text directly after it. Pi's
|
|
196
280
|
differential renderer redraws only the changed cells — no flicker, no
|
|
@@ -201,6 +285,17 @@ Exit code is `0` when all thresholds pass, `1` when any fail, `2` on I/O error o
|
|
|
201
285
|
handles legacy CSI/SS3 sequences and the Kitty keyboard protocol uniformly,
|
|
202
286
|
so kitty / WezTerm / iTerm2 (Kitty-mode) all work. Otherwise the input
|
|
203
287
|
passes through to `super.handleInput`.
|
|
288
|
+
- **Ctrl+Right** accepts the next *word* of the ghost (PRD §M3f). A "word"
|
|
289
|
+
is a run of `\w+` characters, or a single non-word non-whitespace char
|
|
290
|
+
with optional leading whitespace — VS Code's *Cursor Word Right* semantics.
|
|
291
|
+
Repeated presses peel the ghost off one token at a time; the final press
|
|
292
|
+
finalises the metric as `accepted-partial`.
|
|
293
|
+
- **Alt+]** / **Alt+[** cycle through ranked candidates when the provider
|
|
294
|
+
returns more than one (e.g. `openai-compat` with `PI_GHOST_MERCURY_PARALLEL_N>1`
|
|
295
|
+
and `PI_GHOST_TEMPERATURE>0`). Single-candidate sources (cache, trie,
|
|
296
|
+
speculative warm, deterministic path, default LLM fire) treat both keys
|
|
297
|
+
as no-ops. The selected candidate's index is logged as `candidateRank`
|
|
298
|
+
on accept along with `cycledCount`.
|
|
204
299
|
- Visible-column math uses `string-width` + `strip-ansi`. Ghost text is
|
|
205
300
|
clipped grapheme-aware to the remaining columns on the current visual line
|
|
206
301
|
so wide CJK characters and emoji never overflow the row.
|
|
@@ -210,7 +305,7 @@ Exit code is `0` when all thresholds pass, `1` when any fail, `2` on I/O error o
|
|
|
210
305
|
```bash
|
|
211
306
|
npm install
|
|
212
307
|
npm run typecheck # tsc --noEmit against pi-tui / pi-coding-agent v0.74
|
|
213
|
-
npm test # vitest, ~
|
|
308
|
+
npm test # vitest, ~170 unit tests
|
|
214
309
|
npm run build # emits dist/
|
|
215
310
|
```
|
|
216
311
|
|
package/dist/bench-cli.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { unwatchFile, watchFile } from "node:fs";
|
|
2
3
|
import { resolve } from "node:path";
|
|
3
|
-
import { formatReport, runBenchmark } from "./bench.js";
|
|
4
|
+
import { formatReport, renderLiveFrame, runBenchmark } from "./bench.js";
|
|
4
5
|
const DEFAULT_PATH = ".pi/ghost-autocomplete/metrics.jsonl";
|
|
6
|
+
const DEFAULT_LIVE_INTERVAL_MS = 2000;
|
|
5
7
|
async function main() {
|
|
6
8
|
const args = process.argv.slice(2);
|
|
7
9
|
if (args.includes("-h") || args.includes("--help")) {
|
|
@@ -9,8 +11,17 @@ async function main() {
|
|
|
9
11
|
return;
|
|
10
12
|
}
|
|
11
13
|
const wantJson = args.includes("--json");
|
|
14
|
+
const wantLive = args.includes("--live");
|
|
15
|
+
const intervalFlag = args.find((a) => a.startsWith("--interval="));
|
|
16
|
+
const intervalMs = intervalFlag
|
|
17
|
+
? Math.max(250, Number.parseInt(intervalFlag.slice("--interval=".length), 10) || DEFAULT_LIVE_INTERVAL_MS)
|
|
18
|
+
: DEFAULT_LIVE_INTERVAL_MS;
|
|
12
19
|
const positional = args.filter((a) => !a.startsWith("-"));
|
|
13
20
|
const target = resolve(process.cwd(), positional[0] ?? DEFAULT_PATH);
|
|
21
|
+
if (wantLive) {
|
|
22
|
+
await runLive(target, intervalMs);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
14
25
|
try {
|
|
15
26
|
const report = await runBenchmark(target);
|
|
16
27
|
if (wantJson) {
|
|
@@ -32,15 +43,80 @@ async function main() {
|
|
|
32
43
|
process.exit(2);
|
|
33
44
|
}
|
|
34
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Live mode (Enhancement #6): re-render the report whenever `target` changes.
|
|
48
|
+
* Polls via `fs.watchFile` rather than `fs.watch` because the latter is
|
|
49
|
+
* unreliable on Windows for append-only logs. Renders once at startup so
|
|
50
|
+
* the user sees the current state before the first append.
|
|
51
|
+
*
|
|
52
|
+
* Exit on SIGINT. Errors during a refresh are reported inline and the
|
|
53
|
+
* loop continues — a transient I/O hiccup shouldn't kill the watcher.
|
|
54
|
+
*/
|
|
55
|
+
async function runLive(target, intervalMs) {
|
|
56
|
+
let frame = 0;
|
|
57
|
+
let refreshing = false;
|
|
58
|
+
let pendingRefresh = false;
|
|
59
|
+
const refresh = async () => {
|
|
60
|
+
// If a refresh is already in flight, mark the file dirty so we run
|
|
61
|
+
// one more pass after it completes. Without this, two writes during
|
|
62
|
+
// the same render would render only once; subsequent writes wouldn't
|
|
63
|
+
// trigger anything until the watcher saw another mtime change.
|
|
64
|
+
if (refreshing) {
|
|
65
|
+
pendingRefresh = true;
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
refreshing = true;
|
|
69
|
+
try {
|
|
70
|
+
const report = await runBenchmark(target);
|
|
71
|
+
frame++;
|
|
72
|
+
const frameText = renderLiveFrame(report, {
|
|
73
|
+
now: new Date(),
|
|
74
|
+
frameNumber: frame,
|
|
75
|
+
watchedPath: target,
|
|
76
|
+
});
|
|
77
|
+
// ANSI: clear screen + cursor home. Plain-text fallback would just
|
|
78
|
+
// scroll, which is fine in a non-TTY pipe.
|
|
79
|
+
const clearSeq = process.stdout.isTTY ? "\x1b[2J\x1b[H" : "";
|
|
80
|
+
process.stdout.write(`${clearSeq}${frameText}\n`);
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
84
|
+
process.stderr.write(`pi-ghost-bench --live: refresh error: ${msg}\n`);
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
refreshing = false;
|
|
88
|
+
if (pendingRefresh) {
|
|
89
|
+
pendingRefresh = false;
|
|
90
|
+
void refresh();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
process.on("SIGINT", () => {
|
|
95
|
+
unwatchFile(target);
|
|
96
|
+
process.stdout.write("\npi-ghost-bench --live: stopped.\n");
|
|
97
|
+
// Exit with 128 + signal number (130 = 128 + SIGINT/2). Matches the
|
|
98
|
+
// convention shells use when reporting a Ctrl-C terminated process.
|
|
99
|
+
process.exit(130);
|
|
100
|
+
});
|
|
101
|
+
await refresh();
|
|
102
|
+
watchFile(target, { interval: intervalMs }, (curr, prev) => {
|
|
103
|
+
if (curr.mtimeMs !== prev.mtimeMs || curr.size !== prev.size) {
|
|
104
|
+
void refresh();
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
35
108
|
function usage() {
|
|
36
109
|
return [
|
|
37
|
-
"pi-ghost-bench [path] [--json]",
|
|
110
|
+
"pi-ghost-bench [path] [--json] [--live] [--interval=MS]",
|
|
38
111
|
"",
|
|
39
|
-
" path
|
|
40
|
-
" --json
|
|
41
|
-
" -
|
|
112
|
+
" path JSONL metrics file (default: .pi/ghost-autocomplete/metrics.jsonl)",
|
|
113
|
+
" --json Emit JSON instead of formatted text",
|
|
114
|
+
" --live Watch the file and re-render on each change (Ctrl+C to exit)",
|
|
115
|
+
" --interval=MS Poll interval for --live (default: 2000, min: 250)",
|
|
116
|
+
" -h Show this help",
|
|
42
117
|
"",
|
|
43
118
|
"Exit code: 0 if all PRD thresholds pass, 1 if any fail, 2 on I/O error.",
|
|
119
|
+
"--live runs until interrupted (no exit code gating).",
|
|
44
120
|
"",
|
|
45
121
|
].join("\n");
|
|
46
122
|
}
|
package/dist/bench-cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bench-cli.js","sourceRoot":"","sources":["../src/bench-cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"bench-cli.js","sourceRoot":"","sources":["../src/bench-cli.ts"],"names":[],"mappings":"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"}
|
package/dist/bench.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type MetricsRecord } from "./metrics.js";
|
|
2
2
|
/**
|
|
3
3
|
* PRD §Success Metrics initial candidate thresholds. These are red/green
|
|
4
4
|
* targets, not gates — the harness reports compliance but never errors out.
|
|
@@ -9,6 +9,15 @@ export declare const THRESHOLDS: {
|
|
|
9
9
|
readonly deterministicP50Ms: 30;
|
|
10
10
|
readonly validOutputRate: 0.85;
|
|
11
11
|
readonly badOutputRate: 0.15;
|
|
12
|
+
/**
|
|
13
|
+
* Enhancement #6 hard gate: fraction of accepted-or-shown ghosts whose
|
|
14
|
+
* `estimatedTimeSavedMs` came out negative — i.e. the user spent more
|
|
15
|
+
* time waiting for the ghost than the keystrokes the accept could ever
|
|
16
|
+
* save. <10% is healthy, 10–20% warns, ≥20% fails. Calibrated against
|
|
17
|
+
* Yeh/Laban "saved-time" surveys and our own M5 data.
|
|
18
|
+
*/
|
|
19
|
+
readonly negativeTimeSavedYellow: 0.1;
|
|
20
|
+
readonly negativeTimeSavedRed: 0.2;
|
|
12
21
|
};
|
|
13
22
|
export interface ProviderStats {
|
|
14
23
|
provider: string;
|
|
@@ -28,8 +37,9 @@ export interface ProviderStats {
|
|
|
28
37
|
/** (empty + rejected + error) / count */
|
|
29
38
|
badRate: number;
|
|
30
39
|
}
|
|
40
|
+
export type AnyMode = "deterministic" | "llm" | "cache" | "trie" | "speculative-warm" | "provisional";
|
|
31
41
|
export interface ModeStats {
|
|
32
|
-
mode:
|
|
42
|
+
mode: AnyMode;
|
|
33
43
|
count: number;
|
|
34
44
|
shown: number;
|
|
35
45
|
accepted: number;
|
|
@@ -39,17 +49,121 @@ export interface ModeStats {
|
|
|
39
49
|
acceptanceRate: number;
|
|
40
50
|
providers: ProviderStats[];
|
|
41
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Advanced metrics from M5a fields. All optional — values are populated only
|
|
54
|
+
* when the records carry the required field. Skipping rather than zeroing
|
|
55
|
+
* keeps a sparse session from looking artificially well-instrumented.
|
|
56
|
+
*/
|
|
57
|
+
export interface AdvancedStats {
|
|
58
|
+
/** Time-to-first-token (LLM modes), p50/p95 in ms. */
|
|
59
|
+
ttftMs?: {
|
|
60
|
+
p50: number;
|
|
61
|
+
p95: number;
|
|
62
|
+
n: number;
|
|
63
|
+
};
|
|
64
|
+
/** Estimated typing time saved per accepted ghost, p50/p95 in ms. */
|
|
65
|
+
timeSavedMs?: {
|
|
66
|
+
p50: number;
|
|
67
|
+
p95: number;
|
|
68
|
+
total: number;
|
|
69
|
+
n: number;
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Enhancement #6 hard gate: fraction of `estimatedTimeSavedMs` samples
|
|
73
|
+
* that came out negative. `severity`:
|
|
74
|
+
* - "ok": fraction < THRESHOLDS.negativeTimeSavedYellow
|
|
75
|
+
* - "yellow": yellow ≤ fraction < red
|
|
76
|
+
* - "red": fraction ≥ THRESHOLDS.negativeTimeSavedRed
|
|
77
|
+
* `n` is the denominator (records with `estimatedTimeSavedMs`).
|
|
78
|
+
*/
|
|
79
|
+
negativeTimeSaved?: {
|
|
80
|
+
count: number;
|
|
81
|
+
fraction: number;
|
|
82
|
+
n: number;
|
|
83
|
+
severity: "ok" | "yellow" | "red";
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* Accept-regret rate per PRD §M5b: fraction of accepted ghosts the user
|
|
87
|
+
* deleted >50% of within the regret window. Calibration target: <10%.
|
|
88
|
+
* `n` is the denominator (accepted + accepted-partial outcomes).
|
|
89
|
+
*/
|
|
90
|
+
acceptRegretRate?: {
|
|
91
|
+
rate: number;
|
|
92
|
+
n: number;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Enhancement #3: fraction of *dismissed* ghosts where the user dismissed
|
|
96
|
+
* within `PI_GHOST_SHORT_HOVER_MS` (default 800 ms). High rate signals
|
|
97
|
+
* the rerank/confidence gate is letting through low-value candidates.
|
|
98
|
+
* `n` is the denominator (dismissed outcomes).
|
|
99
|
+
*/
|
|
100
|
+
shortHoverDismissRate?: {
|
|
101
|
+
rate: number;
|
|
102
|
+
n: number;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Enhancement #5: fraction of stale records where the user typed at
|
|
106
|
+
* least `TYPED_PAST_DIVERGENT_THRESHOLD` consecutive divergent
|
|
107
|
+
* characters past the served ghost. High rate is a strong signal that
|
|
108
|
+
* the suggestions are off-target for this user's style. `n` is the
|
|
109
|
+
* denominator (stale outcomes).
|
|
110
|
+
*/
|
|
111
|
+
typedPastDivergentRate?: {
|
|
112
|
+
rate: number;
|
|
113
|
+
n: number;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Provisional-fallback stats per PRD §M5b: how often provisional fired,
|
|
117
|
+
* what fraction the LLM ended up matching, and mean swap latency for
|
|
118
|
+
* the cases that did swap.
|
|
119
|
+
*/
|
|
120
|
+
provisional?: {
|
|
121
|
+
shown: number;
|
|
122
|
+
swapped: number;
|
|
123
|
+
correctRate: number;
|
|
124
|
+
meanSwapMs: number;
|
|
125
|
+
/**
|
|
126
|
+
* Fraction of `swapped` events where the user dismissed/aborted within
|
|
127
|
+
* `SWAP_FLICKER_WINDOW_MS` — visual jumps that didn't help. With
|
|
128
|
+
* `PREFER` margin now the default, this should converge to a low
|
|
129
|
+
* single-digit % under normal use.
|
|
130
|
+
*/
|
|
131
|
+
flickerRate?: number;
|
|
132
|
+
/** Per-source counts of provisional shows that survived to outcome
|
|
133
|
+
* WITHOUT being superseded by the LLM (i.e., `mode === "provisional"`
|
|
134
|
+
* on the final record). Keys: `trie`, `profile-accept`,
|
|
135
|
+
* `session-cache`. Provisional+LLM-swap cases are counted under
|
|
136
|
+
* `swapped` instead, because the final shownMetric is the LLM's. */
|
|
137
|
+
bySource?: Record<string, number>;
|
|
138
|
+
/** Accept rate over `shown` — i.e., provisionals that survived alone
|
|
139
|
+
* to outcome (no LLM swap). Measures how good the local guess is
|
|
140
|
+
* when the LLM doesn't take over. Production target: ≥45 %. */
|
|
141
|
+
acceptRate?: number;
|
|
142
|
+
};
|
|
143
|
+
/** Fraction of shown ghosts accepted at first display (rank 0). */
|
|
144
|
+
savedAt1?: number;
|
|
145
|
+
/** Same, after cycling up to 3 candidates. */
|
|
146
|
+
savedAt3?: number;
|
|
147
|
+
/** Same, after 5. */
|
|
148
|
+
savedAt5?: number;
|
|
149
|
+
}
|
|
42
150
|
export interface BenchmarkReport {
|
|
43
151
|
source: string;
|
|
44
152
|
records: number;
|
|
45
153
|
parseErrors: number;
|
|
46
154
|
deterministic: ModeStats;
|
|
47
155
|
llm: ModeStats;
|
|
156
|
+
/** All non-zero modes from the records, keyed by mode name. */
|
|
157
|
+
byMode: ModeStats[];
|
|
158
|
+
advanced: AdvancedStats;
|
|
48
159
|
thresholds: Array<{
|
|
49
160
|
name: string;
|
|
50
161
|
target: string;
|
|
51
162
|
observed: string;
|
|
52
163
|
pass: boolean;
|
|
164
|
+
/** Present when the threshold has a yellow band. "warn" means observed
|
|
165
|
+
* is past the yellow line but still under the red line — pass=true. */
|
|
166
|
+
severity?: "warn";
|
|
53
167
|
}>;
|
|
54
168
|
}
|
|
55
169
|
/**
|
|
@@ -90,4 +204,18 @@ export declare function formatReport(report: BenchmarkReport): string;
|
|
|
90
204
|
* One-shot helper: load a JSONL file and produce a report. Used by the CLI.
|
|
91
205
|
*/
|
|
92
206
|
export declare function runBenchmark(path: string): Promise<BenchmarkReport>;
|
|
207
|
+
/**
|
|
208
|
+
* Enhancement #6: a single rendered "frame" for `pi-ghost-bench --live`.
|
|
209
|
+
* The frame is a self-contained block of text — caller clears the screen
|
|
210
|
+
* and prints it on every metrics-file change. ANSI escapes are emitted by
|
|
211
|
+
* the CLI, not this helper, so the function stays pure and unit-testable.
|
|
212
|
+
*
|
|
213
|
+
* Format: banner with timestamp + frame counter, then the standard
|
|
214
|
+
* formatted report, then a footer with the watched path.
|
|
215
|
+
*/
|
|
216
|
+
export declare function renderLiveFrame(report: BenchmarkReport, opts: {
|
|
217
|
+
now: Date;
|
|
218
|
+
frameNumber: number;
|
|
219
|
+
watchedPath: string;
|
|
220
|
+
}): string;
|
|
93
221
|
//# sourceMappingURL=bench.d.ts.map
|
package/dist/bench.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bench.d.ts","sourceRoot":"","sources":["../src/bench.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"bench.d.ts","sourceRoot":"","sources":["../src/bench.ts"],"names":[],"mappings":"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"}
|