pi-ghost-autocomplete 0.3.2 → 0.4.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.
Files changed (168) hide show
  1. package/LICENSE +561 -0
  2. package/README.md +464 -331
  3. package/dist/bench-cli.js +1 -123
  4. package/dist/bench.d.ts +7 -3
  5. package/dist/bench.js +1 -522
  6. package/dist/config.d.ts +4 -1
  7. package/dist/context-aggregator.d.ts +4 -1
  8. package/dist/cycle-manager.d.ts +2 -21
  9. package/dist/entropy-stop.d.ts +4 -1
  10. package/dist/eval-dataset.d.ts +2 -13
  11. package/dist/fuzzy-matcher.d.ts +4 -1
  12. package/dist/ghost-editor.d.ts +11 -2
  13. package/dist/index.d.ts +4 -1
  14. package/dist/index.js +1 -289
  15. package/dist/intent.d.ts +179 -0
  16. package/dist/metrics.d.ts +4 -1
  17. package/dist/path-index.d.ts +4 -1
  18. package/dist/path-matcher.d.ts +4 -1
  19. package/dist/profile-store.d.ts +4 -1
  20. package/dist/profile.d.ts +2 -20
  21. package/dist/providers/cloud-provider.d.ts +4 -1
  22. package/dist/providers/local-provider.d.ts +4 -1
  23. package/dist/providers/openai-compat-provider.d.ts +24 -1
  24. package/dist/providers/race.d.ts +4 -1
  25. package/dist/providers/types.d.ts +13 -1
  26. package/dist/recent-paths.d.ts +4 -1
  27. package/dist/replay-cli.js +1 -166
  28. package/dist/replay.d.ts +2 -7
  29. package/package.json +90 -80
  30. package/dist/bench-cli.d.ts +0 -3
  31. package/dist/bench-cli.d.ts.map +0 -1
  32. package/dist/bench-cli.js.map +0 -1
  33. package/dist/bench.d.ts.map +0 -1
  34. package/dist/bench.js.map +0 -1
  35. package/dist/cache.d.ts +0 -124
  36. package/dist/cache.d.ts.map +0 -1
  37. package/dist/cache.js +0 -173
  38. package/dist/cache.js.map +0 -1
  39. package/dist/candidate-rerank.d.ts +0 -57
  40. package/dist/candidate-rerank.d.ts.map +0 -1
  41. package/dist/candidate-rerank.js +0 -78
  42. package/dist/candidate-rerank.js.map +0 -1
  43. package/dist/config.d.ts.map +0 -1
  44. package/dist/config.js +0 -317
  45. package/dist/config.js.map +0 -1
  46. package/dist/context-aggregator.d.ts.map +0 -1
  47. package/dist/context-aggregator.js +0 -87
  48. package/dist/context-aggregator.js.map +0 -1
  49. package/dist/context-selector.d.ts +0 -128
  50. package/dist/context-selector.d.ts.map +0 -1
  51. package/dist/context-selector.js +0 -300
  52. package/dist/context-selector.js.map +0 -1
  53. package/dist/cycle-manager.d.ts.map +0 -1
  54. package/dist/cycle-manager.js +0 -168
  55. package/dist/cycle-manager.js.map +0 -1
  56. package/dist/edit-history-ring.d.ts +0 -148
  57. package/dist/edit-history-ring.d.ts.map +0 -1
  58. package/dist/edit-history-ring.js +0 -262
  59. package/dist/edit-history-ring.js.map +0 -1
  60. package/dist/entropy-stop.d.ts.map +0 -1
  61. package/dist/entropy-stop.js +0 -141
  62. package/dist/entropy-stop.js.map +0 -1
  63. package/dist/eval-dataset.d.ts.map +0 -1
  64. package/dist/eval-dataset.js +0 -127
  65. package/dist/eval-dataset.js.map +0 -1
  66. package/dist/fast-path-engine.d.ts +0 -286
  67. package/dist/fast-path-engine.d.ts.map +0 -1
  68. package/dist/fast-path-engine.js +0 -341
  69. package/dist/fast-path-engine.js.map +0 -1
  70. package/dist/fuzzy-matcher.d.ts.map +0 -1
  71. package/dist/fuzzy-matcher.js +0 -162
  72. package/dist/fuzzy-matcher.js.map +0 -1
  73. package/dist/ghost-editor.d.ts.map +0 -1
  74. package/dist/ghost-editor.js +0 -1491
  75. package/dist/ghost-editor.js.map +0 -1
  76. package/dist/index.d.ts.map +0 -1
  77. package/dist/index.js.map +0 -1
  78. package/dist/keystroke-timer.d.ts +0 -59
  79. package/dist/keystroke-timer.d.ts.map +0 -1
  80. package/dist/keystroke-timer.js +0 -94
  81. package/dist/keystroke-timer.js.map +0 -1
  82. package/dist/metrics-builder.d.ts +0 -71
  83. package/dist/metrics-builder.d.ts.map +0 -1
  84. package/dist/metrics-builder.js +0 -71
  85. package/dist/metrics-builder.js.map +0 -1
  86. package/dist/metrics.d.ts.map +0 -1
  87. package/dist/metrics.js +0 -212
  88. package/dist/metrics.js.map +0 -1
  89. package/dist/path-index.d.ts.map +0 -1
  90. package/dist/path-index.js +0 -148
  91. package/dist/path-index.js.map +0 -1
  92. package/dist/path-matcher.d.ts.map +0 -1
  93. package/dist/path-matcher.js +0 -88
  94. package/dist/path-matcher.js.map +0 -1
  95. package/dist/profile-store.d.ts.map +0 -1
  96. package/dist/profile-store.js +0 -199
  97. package/dist/profile-store.js.map +0 -1
  98. package/dist/profile.d.ts.map +0 -1
  99. package/dist/profile.js +0 -434
  100. package/dist/profile.js.map +0 -1
  101. package/dist/providers/cloud-provider.d.ts.map +0 -1
  102. package/dist/providers/cloud-provider.js +0 -109
  103. package/dist/providers/cloud-provider.js.map +0 -1
  104. package/dist/providers/local-provider.d.ts.map +0 -1
  105. package/dist/providers/local-provider.js +0 -48
  106. package/dist/providers/local-provider.js.map +0 -1
  107. package/dist/providers/openai-compat-provider.d.ts.map +0 -1
  108. package/dist/providers/openai-compat-provider.js +0 -215
  109. package/dist/providers/openai-compat-provider.js.map +0 -1
  110. package/dist/providers/openai-completions-runner.d.ts +0 -52
  111. package/dist/providers/openai-completions-runner.d.ts.map +0 -1
  112. package/dist/providers/openai-completions-runner.js +0 -141
  113. package/dist/providers/openai-completions-runner.js.map +0 -1
  114. package/dist/providers/race.d.ts.map +0 -1
  115. package/dist/providers/race.js +0 -441
  116. package/dist/providers/race.js.map +0 -1
  117. package/dist/providers/truncate.d.ts +0 -7
  118. package/dist/providers/truncate.d.ts.map +0 -1
  119. package/dist/providers/truncate.js +0 -57
  120. package/dist/providers/truncate.js.map +0 -1
  121. package/dist/providers/types.d.ts.map +0 -1
  122. package/dist/providers/types.js +0 -60
  123. package/dist/providers/types.js.map +0 -1
  124. package/dist/provisional-manager.d.ts +0 -93
  125. package/dist/provisional-manager.d.ts.map +0 -1
  126. package/dist/provisional-manager.js +0 -98
  127. package/dist/provisional-manager.js.map +0 -1
  128. package/dist/provisional.d.ts +0 -150
  129. package/dist/provisional.d.ts.map +0 -1
  130. package/dist/provisional.js +0 -238
  131. package/dist/provisional.js.map +0 -1
  132. package/dist/recent-paths.d.ts.map +0 -1
  133. package/dist/recent-paths.js +0 -114
  134. package/dist/recent-paths.js.map +0 -1
  135. package/dist/regret-tracker.d.ts +0 -84
  136. package/dist/regret-tracker.d.ts.map +0 -1
  137. package/dist/regret-tracker.js +0 -145
  138. package/dist/regret-tracker.js.map +0 -1
  139. package/dist/replay-cli.d.ts +0 -13
  140. package/dist/replay-cli.d.ts.map +0 -1
  141. package/dist/replay-cli.js.map +0 -1
  142. package/dist/replay.d.ts.map +0 -1
  143. package/dist/replay.js +0 -225
  144. package/dist/replay.js.map +0 -1
  145. package/dist/reranker.d.ts +0 -181
  146. package/dist/reranker.d.ts.map +0 -1
  147. package/dist/reranker.js +0 -324
  148. package/dist/reranker.js.map +0 -1
  149. package/dist/session-trie.d.ts +0 -103
  150. package/dist/session-trie.d.ts.map +0 -1
  151. package/dist/session-trie.js +0 -280
  152. package/dist/session-trie.js.map +0 -1
  153. package/dist/speculative.d.ts +0 -74
  154. package/dist/speculative.d.ts.map +0 -1
  155. package/dist/speculative.js +0 -107
  156. package/dist/speculative.js.map +0 -1
  157. package/dist/tool-summarize.d.ts +0 -40
  158. package/dist/tool-summarize.d.ts.map +0 -1
  159. package/dist/tool-summarize.js +0 -245
  160. package/dist/tool-summarize.js.map +0 -1
  161. package/dist/trie-sanitize.d.ts +0 -22
  162. package/dist/trie-sanitize.d.ts.map +0 -1
  163. package/dist/trie-sanitize.js +0 -142
  164. package/dist/trie-sanitize.js.map +0 -1
  165. package/dist/versions.d.ts +0 -23
  166. package/dist/versions.d.ts.map +0 -1
  167. package/dist/versions.js +0 -31
  168. package/dist/versions.js.map +0 -1
@@ -1,78 +0,0 @@
1
- /**
2
- * Pure rerank pipeline for an LLM `CandidateSet`. Extracted from
3
- * `GhostEditor.requestPrediction` as part of refactor #57 so the editor
4
- * stays thin and the rerank-+-confidence-gate path is unit-testable in
5
- * isolation.
6
- *
7
- * PRD §M3c (weighted reranker) + §M3c.1 (confidence gate) + §M4
8
- * (profile-bias signal). Single-candidate sets bypass the reranker
9
- * entirely — there is no reordering to do and the confidence gate is
10
- * not applicable (it operates on the reranked top-vs-second margin).
11
- *
12
- * No `this`, no I/O, no editor state — caller supplies env strings and
13
- * an optional `profileBias` function.
14
- */
15
- import { applyConfidenceGate, parseMinConfidenceEnv, parseWeightsEnv, rerank, } from "./reranker.js";
16
- /**
17
- * Rerank a candidate set + apply the optional confidence gate. Returns
18
- * `{ gated: true }` when the gate rejected the result (caller should emit
19
- * a `rejected` metric and skip rendering). Otherwise returns the reordered
20
- * candidate texts plus the top pick.
21
- */
22
- export function rerankCandidateSet(input) {
23
- // Empty set is structurally invalid for this function — the caller
24
- // must guard for `!result || !set` BEFORE invoking. Treat as gated so
25
- // any future re-use can't silently render an empty ghost.
26
- if (input.candidates.length === 0) {
27
- return { gated: true };
28
- }
29
- // Single-candidate path: nothing to reorder, gate doesn't apply
30
- // (it needs a top-vs-second margin). Still surface editProximity raw
31
- // score for metric capture when scorer was supplied.
32
- if (input.candidates.length === 1) {
33
- const only = input.candidates[0];
34
- const ep = input.editProximityScorer ? input.editProximityScorer(only.text) : undefined;
35
- return {
36
- gated: false,
37
- candidateTexts: [only.text],
38
- topText: only.text,
39
- ...(ep !== undefined ? { topEditProximityScore: ep } : {}),
40
- };
41
- }
42
- const local = input.providerName === "ghost-local";
43
- const inputs = input.candidates.map((c) => ({
44
- text: c.text,
45
- provider: input.providerName,
46
- local,
47
- ...(c.avgLogprob !== undefined ? { avgLogprob: c.avgLogprob } : {}),
48
- }));
49
- // PRD-adjacent (#5): pass last-line prefix length so the lengthPrior
50
- // curve scales for long-prefix queries. Document-level length would
51
- // over-extend the curve on multi-line buffers; the active line is
52
- // what the user is currently typing.
53
- const lastLinePrefix = input.prefix.split("\n").pop() ?? "";
54
- const ranked = rerank(inputs, {
55
- weights: parseWeightsEnv(input.weightsEnvRaw),
56
- prefixLen: lastLinePrefix.length,
57
- ...(input.profileBias ? { profileBias: input.profileBias } : {}),
58
- ...(input.editProximityScorer ? { editProximityScorer: input.editProximityScorer } : {}),
59
- });
60
- if (input.minConfidenceEnvRaw !== undefined) {
61
- const gated = applyConfidenceGate(ranked, {
62
- minConfidence: parseMinConfidenceEnv(input.minConfidenceEnvRaw),
63
- });
64
- if (!gated)
65
- return { gated: true };
66
- }
67
- const topText = ranked[0].text;
68
- const topEditProximityScore = input.editProximityScorer
69
- ? input.editProximityScorer(topText)
70
- : undefined;
71
- return {
72
- gated: false,
73
- candidateTexts: ranked.map((r) => r.text),
74
- topText,
75
- ...(topEditProximityScore !== undefined ? { topEditProximityScore } : {}),
76
- };
77
- }
78
- //# sourceMappingURL=candidate-rerank.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"candidate-rerank.js","sourceRoot":"","sources":["../src/candidate-rerank.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtE,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,OAAO,GAAG,eAAe,GAAG,MAAM,CAAC;AAExE,MAAM,WAAW,0BAA0B;IAC1C,IAAI,EAAE,eAAe,CAAC;IACtB,8DAA8D;IAC9D,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,aAAa,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IACnC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,KAAK,CAAC,mBAAmB,GAAG,mBAAmB,GAAG,0BAA0B,CAAC,CAAC;IACvF,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,cAAc,GACvB,mBAAmB,GACnB,mBAAmB,GACnB,0BAA0B,GAC1B,kBAAkB,CAAC;AAEtB,MAAM,WAAW,WAAW;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,cAAc,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,oBAAoB,EAAE,mBAQlC,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,mBAQlC,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,0BAUpC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,WAK5B,CAAC;AAqBF,wBAAgB,iBAAiB,IAAI,WAAW,CAwD/C;AAsHD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAI1E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAEzC;AAaD;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,SAAsB,GAAG,MAAM,GAAG,IAAI,CAsB3F"}
package/dist/config.js DELETED
@@ -1,317 +0,0 @@
1
- import { getModels } from "@earendil-works/pi-ai";
2
- export const DEFAULT_CLOUD_CONFIG = {
3
- kind: "cloud",
4
- provider: "groq",
5
- modelId: "llama-3.1-8b-instant",
6
- debounceMs: 150,
7
- maxTokens: 64,
8
- maxRecentMessages: 4,
9
- temperature: 0,
10
- };
11
- export const DEFAULT_LOCAL_CONFIG = {
12
- kind: "local",
13
- baseUrl: "http://localhost:11434",
14
- modelId: "qwen2.5-coder:1.5b",
15
- debounceMs: 400,
16
- maxTokens: 48,
17
- maxRecentMessages: 2,
18
- temperature: 0,
19
- };
20
- export const DEFAULT_MERCURY_CONFIG = {
21
- kind: "openai-compat",
22
- providerName: "mercury-edit",
23
- baseUrl: "https://api.inceptionlabs.ai/v1",
24
- modelId: "mercury-edit-2",
25
- debounceMs: 150,
26
- maxTokens: 64,
27
- maxRecentMessages: 4,
28
- temperature: 0,
29
- parallelN: 1,
30
- };
31
- export const DEFAULT_CONFIG = {
32
- enabled: true,
33
- provider: DEFAULT_MERCURY_CONFIG,
34
- minChars: 3,
35
- maxLineLength: 240,
36
- };
37
- /**
38
- * Default per-provider model id when racing. Models chosen for speed; users
39
- * can override individually with `PI_GHOST_RACE_<NAME>_MODEL`.
40
- */
41
- const RACE_DEFAULT_MODELS = {
42
- groq: "llama-3.1-8b-instant",
43
- cerebras: "llama-3.1-8b",
44
- };
45
- /**
46
- * Aliases recognized as Mercury Edit (Inception Labs). Limited to the brand
47
- * name and the specific model version — broader aliases like bare "mercury"
48
- * or "inception" would lock in a routing that might surprise a user wanting
49
- * a future model from the same vendor.
50
- */
51
- const MERCURY_ALIASES = new Set(["mercury", "mercury-2", "mercury-edit", "mercury-edit-2"]);
52
- const MERCURY_DEFAULT_BASE_URL = "https://api.inceptionlabs.ai/v1";
53
- const MERCURY_DEFAULT_MODEL = "mercury-edit-2";
54
- export function readConfigFromEnv() {
55
- const raceList = process.env.PI_GHOST_RACE_PROVIDERS;
56
- const mode = process.env.PI_GHOST_PROVIDER?.toLowerCase();
57
- const cfg = {
58
- enabled: process.env.PI_GHOST_DISABLED !== "1",
59
- provider: raceList
60
- ? buildRaceFromEnv(raceList)
61
- : mode === "local"
62
- ? { ...DEFAULT_LOCAL_CONFIG }
63
- : mode === "cloud"
64
- ? { ...DEFAULT_CLOUD_CONFIG }
65
- : { ...DEFAULT_MERCURY_CONFIG },
66
- minChars: numEnv("PI_GHOST_MIN_CHARS", DEFAULT_CONFIG.minChars),
67
- maxLineLength: numEnv("PI_GHOST_MAX_LINE", DEFAULT_CONFIG.maxLineLength),
68
- };
69
- if (cfg.provider.kind === "cloud") {
70
- if (process.env.PI_GHOST_PROVIDER_NAME)
71
- cfg.provider.provider = process.env.PI_GHOST_PROVIDER_NAME;
72
- if (process.env.PI_GHOST_MODEL)
73
- cfg.provider.modelId = process.env.PI_GHOST_MODEL;
74
- const apiKey = sanitizeApiKey(process.env.PI_GHOST_API_KEY);
75
- if (apiKey !== undefined)
76
- cfg.provider.apiKey = apiKey;
77
- cfg.provider.debounceMs = numEnv("PI_GHOST_DEBOUNCE_MS", cfg.provider.debounceMs);
78
- cfg.provider.maxTokens = numEnv("PI_GHOST_MAX_TOKENS", cfg.provider.maxTokens);
79
- cfg.provider.maxRecentMessages = numEnv("PI_GHOST_RECENT", cfg.provider.maxRecentMessages);
80
- cfg.provider.temperature = tempEnv(cfg.provider.temperature);
81
- }
82
- else if (cfg.provider.kind === "openai-compat") {
83
- const baseUrlRaw = process.env.PI_GHOST_BASE_URL ?? process.env.INCEPTION_BASE_URL;
84
- if (baseUrlRaw) {
85
- const fieldName = process.env.PI_GHOST_BASE_URL ? "PI_GHOST_BASE_URL" : "INCEPTION_BASE_URL";
86
- const validated = validateBaseUrl(baseUrlRaw, fieldName);
87
- if (validated)
88
- cfg.provider.baseUrl = validated;
89
- }
90
- if (process.env.PI_GHOST_MODEL)
91
- cfg.provider.modelId = process.env.PI_GHOST_MODEL;
92
- const apiKey = sanitizeApiKey(process.env.PI_GHOST_API_KEY ?? process.env.INCEPTION_API_KEY);
93
- if (apiKey !== undefined)
94
- cfg.provider.apiKey = apiKey;
95
- cfg.provider.debounceMs = numEnv("PI_GHOST_DEBOUNCE_MS", cfg.provider.debounceMs);
96
- cfg.provider.maxTokens = numEnv("PI_GHOST_MAX_TOKENS", cfg.provider.maxTokens);
97
- cfg.provider.maxRecentMessages = numEnv("PI_GHOST_RECENT", cfg.provider.maxRecentMessages);
98
- cfg.provider.temperature = tempEnv(cfg.provider.temperature);
99
- cfg.provider.parallelN = parallelNEnv(cfg.provider.parallelN);
100
- }
101
- else if (cfg.provider.kind === "local") {
102
- if (process.env.PI_GHOST_BASE_URL) {
103
- const validated = validateBaseUrl(process.env.PI_GHOST_BASE_URL, "PI_GHOST_BASE_URL");
104
- if (validated)
105
- cfg.provider.baseUrl = validated;
106
- }
107
- if (process.env.PI_GHOST_MODEL)
108
- cfg.provider.modelId = process.env.PI_GHOST_MODEL;
109
- cfg.provider.debounceMs = numEnv("PI_GHOST_DEBOUNCE_MS", cfg.provider.debounceMs);
110
- cfg.provider.maxTokens = numEnv("PI_GHOST_MAX_TOKENS", cfg.provider.maxTokens);
111
- cfg.provider.maxRecentMessages = numEnv("PI_GHOST_RECENT", cfg.provider.maxRecentMessages);
112
- cfg.provider.temperature = tempEnv(cfg.provider.temperature);
113
- }
114
- else if (cfg.provider.kind === "race") {
115
- for (const m of cfg.provider.members) {
116
- m.temperature = tempEnv(m.temperature);
117
- }
118
- }
119
- return cfg;
120
- }
121
- function buildRaceFromEnv(raceList) {
122
- const names = raceList
123
- .split(",")
124
- .map((s) => s.trim().toLowerCase())
125
- .filter((s) => s.length > 0);
126
- const members = [];
127
- for (const name of names) {
128
- const member = buildRaceMember(name);
129
- if (member)
130
- members.push(member);
131
- }
132
- const pauseMs = numEnv("PI_GHOST_RACE_PAUSE_MS", 400);
133
- const cooldownMs = numEnv("PI_GHOST_RACE_COOLDOWN_MS", 1500);
134
- const cutoffMs = numEnv("PI_GHOST_RACE_CUTOFF_MS", 700);
135
- return {
136
- kind: "race",
137
- members,
138
- pauseMs,
139
- cooldownMs,
140
- cutoffMs,
141
- maxRecentMessages: numEnv("PI_GHOST_RECENT", DEFAULT_CLOUD_CONFIG.maxRecentMessages),
142
- };
143
- }
144
- function buildRaceMember(name) {
145
- const upper = name.replace(/[^A-Za-z0-9]/g, "_").toUpperCase();
146
- if (name === "local" || name === "ollama") {
147
- const rawBase = process.env[`PI_GHOST_RACE_${upper}_BASE_URL`];
148
- const baseUrl = rawBase
149
- ? (validateBaseUrl(rawBase, `PI_GHOST_RACE_${upper}_BASE_URL`) ?? DEFAULT_LOCAL_CONFIG.baseUrl)
150
- : DEFAULT_LOCAL_CONFIG.baseUrl;
151
- return {
152
- ...DEFAULT_LOCAL_CONFIG,
153
- baseUrl,
154
- modelId: process.env[`PI_GHOST_RACE_${upper}_MODEL`] ?? DEFAULT_LOCAL_CONFIG.modelId,
155
- };
156
- }
157
- if (MERCURY_ALIASES.has(name)) {
158
- const rawBase = process.env[`PI_GHOST_RACE_${upper}_BASE_URL`] ?? process.env.INCEPTION_BASE_URL;
159
- const baseUrl = rawBase
160
- ? (validateBaseUrl(rawBase, `PI_GHOST_RACE_${upper}_BASE_URL`) ?? MERCURY_DEFAULT_BASE_URL)
161
- : MERCURY_DEFAULT_BASE_URL;
162
- const modelId = process.env[`PI_GHOST_RACE_${upper}_MODEL`] ?? MERCURY_DEFAULT_MODEL;
163
- const apiKey = sanitizeApiKey(process.env[`PI_GHOST_RACE_${upper}_API_KEY`] ?? process.env.INCEPTION_API_KEY);
164
- return {
165
- kind: "openai-compat",
166
- providerName: "mercury-edit",
167
- baseUrl,
168
- modelId,
169
- ...(apiKey !== undefined ? { apiKey } : {}),
170
- debounceMs: DEFAULT_CLOUD_CONFIG.debounceMs,
171
- maxTokens: DEFAULT_CLOUD_CONFIG.maxTokens,
172
- maxRecentMessages: DEFAULT_CLOUD_CONFIG.maxRecentMessages,
173
- temperature: DEFAULT_MERCURY_CONFIG.temperature,
174
- parallelN: DEFAULT_MERCURY_CONFIG.parallelN,
175
- };
176
- }
177
- const provider = name;
178
- if (!isKnownCloudProvider(provider)) {
179
- process.stderr.write(`Pi Ghost: ignoring unknown race provider '${name}' in PI_GHOST_RACE_PROVIDERS\n`);
180
- return null;
181
- }
182
- const modelEnv = process.env[`PI_GHOST_RACE_${upper}_MODEL`];
183
- const modelId = modelEnv ?? RACE_DEFAULT_MODELS[provider] ?? DEFAULT_CLOUD_CONFIG.modelId;
184
- const apiKey = sanitizeApiKey(process.env[`PI_GHOST_RACE_${upper}_API_KEY`]);
185
- return {
186
- ...DEFAULT_CLOUD_CONFIG,
187
- provider,
188
- modelId,
189
- ...(apiKey !== undefined ? { apiKey } : {}),
190
- };
191
- }
192
- /**
193
- * Return true when pi-ai recognizes `name` as a cloud provider with at least
194
- * one registered model. Used at config-parse time to reject typos in
195
- * `PI_GHOST_RACE_PROVIDERS` before they cause repeated runtime errors.
196
- */
197
- function isKnownCloudProvider(name) {
198
- try {
199
- const models = getModels(name);
200
- return Array.isArray(models) && models.length > 0;
201
- }
202
- catch {
203
- return false;
204
- }
205
- }
206
- function numEnv(name, fallback) {
207
- const raw = process.env[name];
208
- if (!raw)
209
- return fallback;
210
- const v = Number(raw);
211
- return Number.isFinite(v) && v >= 0 ? v : fallback;
212
- }
213
- /**
214
- * Parse PI_GHOST_TEMPERATURE. Returns fallback when unset or out of [0, 2].
215
- * The provider implementations use 0 by default; users can opt back in to
216
- * sampling for cache-miss diversity. Note: temperature=0 is best-effort
217
- * across vendors and does NOT guarantee identical outputs across calls
218
- * (kernel scheduling / batching cause variance). The completion cache is
219
- * the real determinism guarantee.
220
- */
221
- function tempEnv(fallback) {
222
- const raw = process.env.PI_GHOST_TEMPERATURE;
223
- if (raw === undefined)
224
- return fallback;
225
- const v = Number(raw);
226
- return Number.isFinite(v) && v >= 0 && v <= 2 ? v : fallback;
227
- }
228
- /**
229
- * Strip CR/LF and surrounding whitespace from an API key (SEC-7). Prevents
230
- * HTTP header injection via `Authorization: Bearer ${apiKey}` when a
231
- * malformed `.env` file or environment manipulation injects newlines.
232
- * Returns undefined for empty results so callers fall back to env lookup.
233
- */
234
- export function sanitizeApiKey(raw) {
235
- if (raw === undefined)
236
- return undefined;
237
- const cleaned = raw.replace(/[\r\n]/g, "").trim();
238
- return cleaned.length > 0 ? cleaned : undefined;
239
- }
240
- /**
241
- * Produce a deep copy of a config with all `apiKey` fields removed (SEC-8).
242
- * Use before any logging, diagnostics dump, telemetry, or serialization.
243
- * The original config remains live with its keys for actual provider use.
244
- *
245
- * Defensive: even fields not currently typed as containing keys are scrubbed
246
- * via a recursive walk that drops any property named `apiKey` (case-sensitive).
247
- *
248
- * Caveats: class instances become plain objects (methods lost). Cyclic
249
- * structures would recurse infinitely — caller must ensure acyclic input.
250
- * Both caveats are fine for `GhostConfig` which is plain JSON-shaped.
251
- */
252
- export function redactConfig(cfg) {
253
- return redactWalk(cfg);
254
- }
255
- function redactWalk(value) {
256
- if (value === null || typeof value !== "object")
257
- return value;
258
- if (Array.isArray(value))
259
- return value.map(redactWalk);
260
- const out = {};
261
- for (const [k, v] of Object.entries(value)) {
262
- if (k === "apiKey")
263
- continue;
264
- out[k] = redactWalk(v);
265
- }
266
- return out;
267
- }
268
- /**
269
- * Validate a provider baseUrl (SEC-1). Returns the URL on success, null
270
- * on failure with a stderr warning. Rules:
271
- * - Must be a parseable absolute URL.
272
- * - `https:` always allowed.
273
- * - `http:` only allowed for `localhost` / `127.0.0.1` / `::1` — sending
274
- * API keys + prompt context in cleartext to anything else is almost
275
- * certainly a misconfiguration. Setting `PI_GHOST_ALLOW_INSECURE=1`
276
- * bypasses this check.
277
- * - Other schemes (`file:`, `data:`, etc.) rejected unconditionally.
278
- */
279
- export function validateBaseUrl(raw, fieldName = "PI_GHOST_BASE_URL") {
280
- let url;
281
- try {
282
- url = new URL(raw);
283
- }
284
- catch {
285
- process.stderr.write(`Pi Ghost: ignoring invalid ${fieldName}=${raw}\n`);
286
- return null;
287
- }
288
- if (url.protocol === "https:")
289
- return raw;
290
- if (url.protocol === "http:") {
291
- const host = url.hostname;
292
- if (host === "localhost" || host === "127.0.0.1" || host === "::1")
293
- return raw;
294
- if (process.env.PI_GHOST_ALLOW_INSECURE === "1")
295
- return raw;
296
- process.stderr.write(`Pi Ghost: refusing to use insecure ${fieldName}=${raw} (set PI_GHOST_ALLOW_INSECURE=1 to override)\n`);
297
- return null;
298
- }
299
- process.stderr.write(`Pi Ghost: rejecting ${fieldName} with unsupported scheme '${url.protocol}'\n`);
300
- return null;
301
- }
302
- /**
303
- * Parse PI_GHOST_MERCURY_PARALLEL_N. Returns fallback when unset, non-integer,
304
- * or outside [1, 8]. The upper bound prevents accidental cost explosions —
305
- * each parallel call costs the same as a normal completion.
306
- */
307
- function parallelNEnv(fallback) {
308
- const raw = process.env.PI_GHOST_MERCURY_PARALLEL_N;
309
- if (raw === undefined)
310
- return fallback;
311
- const v = Number(raw);
312
- if (!Number.isFinite(v))
313
- return fallback;
314
- const n = Math.floor(v);
315
- return n >= 1 && n <= 8 ? n : fallback;
316
- }
317
- //# sourceMappingURL=config.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"context-aggregator.d.ts","sourceRoot":"","sources":["../src/context-aggregator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAgB,MAAM,iCAAiC,CAAC;AACtF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAElE;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAChC,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAO,GACnC,aAAa,EAAE,CA0BjB;AAmCD,wBAAgB,WAAW,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAYrD"}
@@ -1,87 +0,0 @@
1
- /**
2
- * Read up to `max` recent messages from the current branch. By default
3
- * returns user + assistant entries; pass `includeTools: true` to also
4
- * surface tool calls/results as `role: "tool"` entries with `toolName`
5
- * populated where available. Returns oldest-first.
6
- */
7
- export function getRecentMessages(ctx, max, opts = {}) {
8
- if (max <= 0)
9
- return [];
10
- const branch = safeBranch(ctx);
11
- if (!branch)
12
- return [];
13
- const includeTools = opts.includeTools ?? false;
14
- const out = [];
15
- for (let i = branch.length - 1; i >= 0 && out.length < max; i--) {
16
- const entry = branch[i];
17
- if (!entry || entry.type !== "message")
18
- continue;
19
- const role = roleOf(entry.message);
20
- if (role === "user" || role === "assistant") {
21
- const text = extractText(entry.message);
22
- if (!text)
23
- continue;
24
- out.push({ role, text });
25
- continue;
26
- }
27
- if (includeTools && role === "tool") {
28
- const text = extractText(entry.message);
29
- if (!text)
30
- continue;
31
- const toolName = toolNameOf(entry.message);
32
- out.push(toolName ? { role: "tool", text, toolName } : { role: "tool", text });
33
- }
34
- }
35
- out.reverse();
36
- return out;
37
- }
38
- /**
39
- * Best-effort extraction of the tool name from an `AgentMessage`. Tool
40
- * messages may carry the name on either the message itself or on a
41
- * tool_use/tool_result content part — handle both shapes.
42
- */
43
- function toolNameOf(msg) {
44
- if (!msg || typeof msg !== "object")
45
- return undefined;
46
- if ("name" in msg && typeof msg.name === "string")
47
- return msg.name;
48
- if ("content" in msg && Array.isArray(msg.content)) {
49
- for (const c of msg.content) {
50
- if (c && typeof c === "object" && "name" in c && typeof c.name === "string") {
51
- return c.name;
52
- }
53
- }
54
- }
55
- return undefined;
56
- }
57
- function safeBranch(ctx) {
58
- try {
59
- return ctx.sessionManager.getBranch();
60
- }
61
- catch {
62
- return undefined;
63
- }
64
- }
65
- function roleOf(msg) {
66
- if (msg && typeof msg === "object" && "role" in msg && typeof msg.role === "string") {
67
- return msg.role;
68
- }
69
- return undefined;
70
- }
71
- export function extractText(msg) {
72
- if (!msg || typeof msg !== "object" || !("content" in msg))
73
- return "";
74
- const content = msg.content;
75
- if (typeof content === "string")
76
- return content.trim();
77
- if (!Array.isArray(content))
78
- return "";
79
- const parts = [];
80
- for (const c of content) {
81
- if (c && typeof c === "object" && "type" in c && c.type === "text" && "text" in c && typeof c.text === "string") {
82
- parts.push(c.text);
83
- }
84
- }
85
- return parts.join("").trim();
86
- }
87
- //# sourceMappingURL=context-aggregator.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"context-aggregator.js","sourceRoot":"","sources":["../src/context-aggregator.ts"],"names":[],"mappings":"AAcA;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAChC,GAAqB,EACrB,GAAW,EACX,OAAmC,EAAE;IAErC,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACxB,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC;IAEvB,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,IAAI,KAAK,CAAC;IAChD,MAAM,GAAG,GAAoB,EAAE,CAAC;IAChC,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QACjE,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;YAAE,SAAS;QACjD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACnC,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;YAC7C,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACxC,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACzB,SAAS;QACV,CAAC;QACD,IAAI,YAAY,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACxC,IAAI,CAAC,IAAI;gBAAE,SAAS;YACpB,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC3C,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAChF,CAAC;IACF,CAAC;IACD,GAAG,CAAC,OAAO,EAAE,CAAC;IACd,OAAO,GAAG,CAAC;AACZ,CAAC;AAED;;;;GAIG;AACH,SAAS,UAAU,CAAC,GAAiB;IACpC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACtD,IAAI,MAAM,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,GAAG,CAAC,IAAI,CAAC;IACnE,IAAI,SAAS,IAAI,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QACpD,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC7E,OAAO,CAAC,CAAC,IAAI,CAAC;YACf,CAAC;QACF,CAAC;IACF,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,SAAS,UAAU,CAAC,GAAqB;IACxC,IAAI,CAAC;QACJ,OAAO,GAAG,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;AACF,CAAC;AAED,SAAS,MAAM,CAAC,GAAiB;IAChC,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACrF,OAAO,GAAG,CAAC,IAAI,CAAC;IACjB,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAiB;IAC5C,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IACtE,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;IAC5B,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC,IAAI,EAAE,CAAC;IACvD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IACvC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACjH,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AAC9B,CAAC"}
@@ -1,128 +0,0 @@
1
- /**
2
- * Relevance-pruned context selection. See PRD §M6b.
3
- *
4
- * Replaces the "last N messages" recency window with a scan-then-select
5
- * design motivated by ChaI-TeA (RESEARCH §2): models can exploit distant
6
- * conversation history; a pure recency window blinds the selector to
7
- * high-IDF distant turns.
8
- *
9
- * Pipeline:
10
- * 1. Scan up to `maxScan` candidates from the branch (newest first).
11
- * 2. Tokenize each candidate's text (lower-case, drop stopwords).
12
- * 3. Score each candidate as `0.7 * recencyWeight + 0.3 * bm25Score`,
13
- * both normalized to [0, 1].
14
- * 4. Sort by score, take top `maxSelected`, enforce `maxChars` budget by
15
- * truncating the lowest-recency tail.
16
- *
17
- * Pure module: no I/O, no editor state.
18
- */
19
- export declare const DEFAULT_MAX_SCAN = 200;
20
- export declare const DEFAULT_MAX_SELECTED = 8;
21
- export declare const DEFAULT_MAX_CHARS = 4000;
22
- export declare const DEFAULT_BM25_WEIGHT = 0.3;
23
- /**
24
- * Enhancement #1: weight on the edit-history token-overlap locality
25
- * signal. Default 0 (opt-in). When > 0, the score formula becomes:
26
- * `score = (1 - bm25Weight - editLocalityWeight) * recency
27
- * + bm25Weight * bm25
28
- * + editLocalityWeight * editLocality`
29
- * where `editLocality` is 1 if the candidate text shares any token with
30
- * `editTokens`, else 0. `bm25Weight + editLocalityWeight` is clamped to
31
- * 1; recency coefficient gets whatever remains.
32
- */
33
- export declare const DEFAULT_EDIT_LOCALITY_WEIGHT = 0;
34
- export declare const RECENCY_HALF_LIFE = 4;
35
- /**
36
- * Small fixed English stopword list. No language detection — when ghost
37
- * autocomplete moves to non-English prompts, this set may need expansion
38
- * or a per-language switch. Until then, the cost of leaving these in is
39
- * higher than the cost of an English-only set.
40
- */
41
- export declare const STOPWORDS: ReadonlySet<string>;
42
- export interface ContextCandidate {
43
- role: "user" | "assistant" | "tool";
44
- text: string;
45
- toolName?: string;
46
- }
47
- export interface ContextSelectorOpts {
48
- maxScan?: number;
49
- maxSelected?: number;
50
- maxChars?: number;
51
- /** Weight on BM25 vs recency: score = (1 - w) * recency + w * bm25. */
52
- bm25Weight?: number;
53
- /**
54
- * Enhancement #1: weight on the edit-history token-overlap bonus.
55
- * Default 0. Requires `editTokens` to have any effect.
56
- */
57
- editLocalityWeight?: number;
58
- /**
59
- * Enhancement #1: set of tokens recently added in nearby edits. A
60
- * candidate whose text contains any of these tokens earns the full
61
- * `editLocalityWeight` bonus. Missing or empty → no effect.
62
- */
63
- editTokens?: ReadonlySet<string>;
64
- }
65
- export interface SelectedContext {
66
- candidates: ContextCandidate[];
67
- scannedCount: number;
68
- selectedCount: number;
69
- totalChars: number;
70
- }
71
- /**
72
- * Tokenize text into lower-case alphanumeric words, dropping stopwords and
73
- * single-character noise. Kept intentionally simple — proper tokenization
74
- * (subword, punctuation handling, code identifiers) would over-fit the
75
- * v0.5 prompt corpus.
76
- *
77
- * Caveat: camelCase identifiers do NOT split. `getRecentMessages` becomes a
78
- * single token `getrecentmessages`. File paths and snake_case split on the
79
- * separator characters and tokenize as expected.
80
- */
81
- export declare function tokenize(text: string): string[];
82
- /**
83
- * Compute document frequencies over a candidate pool. Used as the corpus
84
- * for BM25's IDF term.
85
- */
86
- export declare function computeDocFreqs(candidates: ContextCandidate[]): {
87
- docFreqs: Map<string, number>;
88
- avgDocLen: number;
89
- docLens: number[];
90
- };
91
- /**
92
- * BM25 score for `queryTokens` against a document. Uses an IDF floor
93
- * `log(1 + 1/N)` so terms appearing in every candidate still contribute a
94
- * small positive score instead of zero — PRD §M6b "BM25-on-small-corpus
95
- * caveat".
96
- */
97
- export declare function bm25Score(queryTokens: string[], docTokens: string[], docFreqs: Map<string, number>, N: number, avgDocLen: number): number;
98
- /**
99
- * Exponential recency weight: 1.0 at the newest position, decays e-fold
100
- * every `RECENCY_HALF_LIFE` positions. `distance` is positions from the
101
- * newest end of the candidate pool (0 = newest).
102
- */
103
- export declare function recencyWeight(distance: number): number;
104
- /**
105
- * Select the most relevant subset of `candidates` for the current prefix.
106
- * `candidates` should be newest-first (index 0 = newest). Returns selected
107
- * entries in their original branch order (oldest-first of those selected)
108
- * for natural prompt rendering.
109
- */
110
- export declare function selectContext(candidates: ContextCandidate[], prefix: string, opts?: ContextSelectorOpts): SelectedContext;
111
- /**
112
- * Parse `PI_GHOST_CONTEXT_BM25_WEIGHT`. Returns fallback on bad input or
113
- * outside [0, 1].
114
- */
115
- export declare function parseBm25WeightEnv(raw: string | undefined): number;
116
- /**
117
- * Parse `PI_GHOST_CONTEXT_EDIT_LOCALITY_WEIGHT`. Returns 0 (no-op) on bad
118
- * input or outside [0, 1]. Enhancement #1.
119
- */
120
- export declare function parseEditLocalityWeightEnv(raw: string | undefined): number;
121
- /**
122
- * Build a `ContextSelectorOpts` from the documented env knobs (PRD §M6d).
123
- * Returns a defaulted opts object. `editTokens` is omitted — the caller
124
- * must inject the live edit-history token set on each call (env can only
125
- * configure the weight, not the dynamic data).
126
- */
127
- export declare function readContextEnv(): Omit<Required<ContextSelectorOpts>, "editTokens">;
128
- //# sourceMappingURL=context-selector.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"context-selector.d.ts","sourceRoot":"","sources":["../src/context-selector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,eAAO,MAAM,gBAAgB,MAAM,CAAC;AACpC,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC,eAAO,MAAM,iBAAiB,OAAO,CAAC;AACtC,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC;;;;;;;;;GASG;AACH,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAC9C,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAKnC;;;;;GAKG;AACH,eAAO,MAAM,SAAS,EAAE,WAAW,CAAC,MAAM,CAexC,CAAC;AAEH,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC/B,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAS/C;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,gBAAgB,EAAE,GAAG;IAChE,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;CAClB,CAiBA;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CACxB,WAAW,EAAE,MAAM,EAAE,EACrB,SAAS,EAAE,MAAM,EAAE,EACnB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,CAAC,EAAE,MAAM,EACT,SAAS,EAAE,MAAM,GACf,MAAM,CAyBR;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEtD;AAeD;;;;;GAKG;AACH,wBAAgB,aAAa,CAC5B,UAAU,EAAE,gBAAgB,EAAE,EAC9B,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,mBAAwB,GAC5B,eAAe,CAiGjB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAKlE;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAK1E;AAUD;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,YAAY,CAAC,CAUlF"}