pi-ghost-autocomplete 0.11.0 → 0.12.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.
@@ -0,0 +1,90 @@
1
+ /**
2
+ * SPDX-License-Identifier: SSPL-1.0
3
+ * SPDX-FileCopyrightText: 2025 Alessandro Pungitore <alessandro@pungitore.ch>
4
+ */
5
+ import type { CompletionRegister } from "./intent.js";
6
+ export interface IntentClassifierOptions {
7
+ /** Per-consult abort timeout. Default 400 ms (`PI_GHOST_INTENT_CLASSIFIER_TIMEOUT_MS`). */
8
+ timeoutMs: number;
9
+ /** Minimum answer confidence to apply a verdict. Default 0.6 (`PI_GHOST_INTENT_CLASSIFIER_MIN_CONFIDENCE`). */
10
+ minConfidence: number;
11
+ /** Verdict cache TTL. Default 60 s. */
12
+ ttlMs: number;
13
+ /** Verdict cache capacity (insertion-order eviction). Default 64. */
14
+ capacity: number;
15
+ /** Draft-prefix length the cache keys on. Default 32 chars. */
16
+ keyPrefixLen: number;
17
+ /**
18
+ * Debounce for the consult itself — a keystroke burst collapses into one
19
+ * classify call on the latest draft (the pending-set alone can't dedupe:
20
+ * every keystroke changes the cache key). Default 120 ms
21
+ * (`PI_GHOST_INTENT_CLASSIFIER_DEBOUNCE_MS`, clamped [0, 1000]).
22
+ */
23
+ consultDebounceMs: number;
24
+ now?: () => number;
25
+ }
26
+ /**
27
+ * Gate for consulting the classifier. Pure. True only when the heuristic
28
+ * marked the classification low-confidence AND the draft is long enough to
29
+ * classify meaningfully. Uses display width (string-width), matching the
30
+ * editor's completion gate — a 2-char CJK draft at the default `minChars=4`
31
+ * displays 4 columns wide, reaches the LLM, and must also be classifiable.
32
+ */
33
+ export declare function shouldConsultClassifier(confidence: "high" | "low" | undefined, draft: string, minChars: number): boolean;
34
+ /** Truncated, trimmed draft the verdict cache keys on. Exported for tests. */
35
+ export declare function verdictCacheKey(draft: string, keyPrefixLen: number): string;
36
+ /** The classification question handed to the classifier model. Pure. */
37
+ export declare function buildClassifierContext(draft: string): unknown;
38
+ /** Parse `PI_GHOST_INTENT_CLASSIFIER_TIMEOUT_MS` (clamped to [50, 5000]). */
39
+ export declare function classifierTimeoutFromEnv(raw: string | undefined, fallback: number): number;
40
+ /** Parse `PI_GHOST_INTENT_CLASSIFIER_MIN_CONFIDENCE` (clamped to [0, 1]). */
41
+ export declare function classifierMinConfidenceFromEnv(raw: string | undefined, fallback: number): number;
42
+ /** Parse `PI_GHOST_INTENT_CLASSIFIER_DEBOUNCE_MS` (clamped to [0, 1000]). */
43
+ export declare function classifierConsultDebounceFromEnv(raw: string | undefined, fallback: number): number;
44
+ export declare class IntentClassifier {
45
+ readonly spec: string;
46
+ private readonly registry;
47
+ private readonly opts;
48
+ private readonly classifyFn;
49
+ /** Resolved classifier model (any provider), or null when unresolvable. */
50
+ private modelPromise;
51
+ private readonly verdicts;
52
+ private readonly pending;
53
+ /** Consult debounce: keystroke bursts collapse into one classify call. */
54
+ private consultTimer;
55
+ private consultDraft;
56
+ private constructor();
57
+ /**
58
+ * Build from a config spec. Returns null when disabled (`off`/empty),
59
+ * when the host registry has no `classify` (pi < 0.99), or — for an
60
+ * explicit `provider/model-id` spec — when the typed lookup methods are
61
+ * absent. Model *resolution* stays lazy: `auto` needs the async
62
+ * `getAvailableOfType`, so an unavailable model degrades per-consult
63
+ * (no verdict) rather than disabling the feature at startup.
64
+ */
65
+ static create(spec: string, registry: unknown, opts?: Partial<IntentClassifierOptions>): IntentClassifier | null;
66
+ /** Resolve (once) the classifier model the spec names or auto-picks. */
67
+ private resolveModel;
68
+ private doResolveModel;
69
+ /**
70
+ * Fire-and-forget consult request. Rapid calls (one per keystroke)
71
+ * collapse into a single classify on the latest draft after
72
+ * {@link IntentClassifierOptions.consultDebounceMs} of quiet — the
73
+ * pending-set alone cannot dedupe because every keystroke changes the
74
+ * cache key. Never blocks, never throws.
75
+ */
76
+ maybeConsult(draft: string): void;
77
+ private fireConsult;
78
+ private storeVerdict;
79
+ /**
80
+ * Fresh verdict for the draft's cache key, or null. Prefix-aware: a
81
+ * verdict consulted on an earlier prefix of the same line applies as
82
+ * the line grows (and, symmetrically, after backspacing into it), so
83
+ * the classification of a line's opening sticks without re-consulting
84
+ * per keystroke. Strong-classification gating in the editor bounds any
85
+ * stale-prefix reuse.
86
+ */
87
+ verdictFor(draft: string): CompletionRegister | null;
88
+ /** Number of live verdicts — surfaced in `/ghost` diagnostics. */
89
+ get verdictCount(): number;
90
+ }
package/dist/intent.d.ts CHANGED
@@ -221,6 +221,18 @@ export interface IntentClassification {
221
221
  intent: PromptIntent;
222
222
  register: CompletionRegister;
223
223
  proseReason?: ProseReason;
224
+ /**
225
+ * Heuristic signal strength (track C). `"low"` marks the two weak spots
226
+ * of the regex pipeline — single-line prose (persona split between
227
+ * `general-prose` and `agent-message` is guesswork below 4 lines of
228
+ * context) and the final fallback `instruction` (no verb, marker, or
229
+ * question shape matched — the draft could equally be code like
230
+ * `npm install`). The editor consults the optional intent classifier
231
+ * (pi ≥ 0.99 `registry.classify`, e.g. Jev or a llama.cpp classifier)
232
+ * only for `"low"` classifications, so strong signals never pay the
233
+ * round-trip. Absent means `"high"` (pre-track-C callers).
234
+ */
235
+ confidence?: "high" | "low";
224
236
  }
225
237
  /**
226
238
  * Detailed variant of `classifyPromptIntent`. Same classification order,