dsh-context-compression-improved 0.5.1 → 0.5.3

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 (57) hide show
  1. package/.gitattributes +1 -0
  2. package/CHANGELOG.ja.md +144 -83
  3. package/CHANGELOG.ko.md +143 -82
  4. package/CHANGELOG.md +278 -212
  5. package/CHANGELOG.zh.md +131 -77
  6. package/docs/installation.md +103 -103
  7. package/docs/installation.zh.md +100 -100
  8. package/package.json +1 -1
  9. package/packages/selector/cordis.patch.yml +5 -6
  10. package/packages/selector/lib/advisor-state.js +4 -231
  11. package/packages/selector/lib/client.d.ts +0 -24
  12. package/packages/selector/lib/client.js +6 -501
  13. package/packages/selector/lib/index.d.ts +4 -10
  14. package/packages/selector/lib/index.js +16 -234
  15. package/packages/selector/lib/pruner.d.ts +13 -248
  16. package/packages/selector/lib/pruner.js +148 -552
  17. package/packages/selector/src/client/EstimatorControls.tsx +0 -101
  18. package/packages/selector/src/client/index.ts +0 -17
  19. package/packages/selector/src/client/locales.ts +0 -38
  20. package/packages/selector/src/client/preset-options.ts +3 -2
  21. package/packages/selector/src/client/settings-section.tsx +8 -17
  22. package/packages/selector/src/index.ts +24 -271
  23. package/packages/selector/src/profiles.ts +4 -27
  24. package/packages/selector/src/pruner/state.ts +2 -25
  25. package/packages/selector/src/pruner.ts +75 -403
  26. package/packages/selector/src/runtime/audit.ts +27 -21
  27. package/packages/selector/src/runtime/config.ts +6 -32
  28. package/packages/selector/src/runtime/tokenpilot/advisor-prompt.ts +188 -188
  29. package/packages/selector/src/runtime/tokenpilot/advisor-state.ts +149 -133
  30. package/packages/selector/src/runtime/tokenpilot/advisor.ts +419 -419
  31. package/packages/selector/src/runtime/tokenpilot/benefit.ts +200 -0
  32. package/packages/selector/src/runtime/types.ts +0 -17
  33. package/packages/selector/tests/advisor-report.host.spec.ts +223 -223
  34. package/packages/selector/tests/preset-options-write.client.spec.ts +7 -23
  35. package/packages/selector/tests/public/package-contract.client.spec.ts +20 -0
  36. package/packages/selector/tests/runtime/advice-never-withholds.host.spec.ts +232 -0
  37. package/packages/selector/tests/runtime/advisor-invariant.spec.ts +272 -272
  38. package/packages/selector/tests/runtime/advisor.spec.ts +226 -226
  39. package/packages/selector/tests/runtime/audit.spec.ts +35 -21
  40. package/packages/selector/tests/runtime/char-basis.spec.ts +30 -30
  41. package/packages/selector/tests/runtime/deprecated-preset-options.spec.ts +96 -0
  42. package/packages/selector/tests/runtime/tokenpilot/benefit.spec.ts +217 -0
  43. package/packages/selector/tests/runtime/tokenpilot/profile-baseline.spec.ts +4 -5
  44. package/packages/selector/tests/settings-seat.client.spec.ts +45 -14
  45. package/scripts/toolclass-corpus-replay.mjs +281 -281
  46. package/packages/selector/src/client/ReviewOverlay.tsx +0 -320
  47. package/packages/selector/src/client/review-scope.ts +0 -16
  48. package/packages/selector/src/runtime/tokenpilot/proposal.ts +0 -267
  49. package/packages/selector/src/runtime/tokenpilot/review-queue.ts +0 -231
  50. package/packages/selector/src/runtime/tokenpilot/review-registry.ts +0 -117
  51. package/packages/selector/src/runtime/tokenpilot/review-storage.ts +0 -122
  52. package/packages/selector/tests/review-overlay.client.spec.tsx +0 -118
  53. package/packages/selector/tests/review-routes-registry.host.spec.ts +0 -142
  54. package/packages/selector/tests/review-routes.host.spec.ts +0 -290
  55. package/packages/selector/tests/runtime/tokenpilot/proposal.spec.ts +0 -393
  56. package/packages/selector/tests/runtime/tokenpilot/pruner-review.spec.ts +0 -382
  57. package/packages/selector/tests/runtime/tokenpilot/review-queue.spec.ts +0 -168
@@ -0,0 +1,200 @@
1
+ /**
2
+ * TokenPilot-inspired benefit model — **advisory only**.
3
+ *
4
+ * This module prices one pass's planned replacements as ONE merged mutation and
5
+ * labels the batch with the band the model would have chosen. The label is
6
+ * ADVICE: nothing here suppresses, delays, or rewrites a reduction. The former
7
+ * human-gated review pipeline consumed these bands to withhold the batch from
8
+ * landing; that gate was retired because a reduction must never block automatic
9
+ * processing. The bands now feed the `reduction-advice` audit and the advisor
10
+ * report, and every planned replacement that the rule engine produced lands.
11
+ *
12
+ * Cache accounting (TokenPilot paper): one merged mutation pays a one-time tail
13
+ * KV-cache refill penalty of `(1−α)·tailTokens`, and every later turn recovers
14
+ * the reclaimed tokens at the cache-hit discount `α`:
15
+ *
16
+ * ```
17
+ * R = Σ(tokensBefore − tokensAfter) // net reclaimed tokens
18
+ * paybackTurns = (1−α)·tailTokens / (α·R) // one-time refill / per-turn saving
19
+ * expectedSaving = α·R·max(0, Ŝ − paybackTurns) // Ŝ = estimated remaining turns
20
+ * ```
21
+ *
22
+ * The refill penalty only models mutations of already-cached context. A
23
+ * fresh-stage batch (shaped before its first request) is exempt via
24
+ * `refillPenaltyExempt`: payback is 0 and every reclaimed token saves from
25
+ * the very first turn. Without that exemption every realistic fresh batch
26
+ * prices into the `not-worth-it` band, which makes the advice useless exactly
27
+ * where it is most often consulted.
28
+ *
29
+ * `expectedSaving` is only produced when Ŝ is known (the estimator answered
30
+ * with `expectedRemainingTurns`); it is never fabricated from a guess.
31
+ *
32
+ * Pure functions only: the classifier needs no I/O, no session state, and no
33
+ * host services, so every label is unit-testable and audit-replayable.
34
+ */
35
+
36
+ /** The minimal per-candidate face the benefit model consumes. */
37
+ export interface BenefitCandidate {
38
+ readonly sourceSeq: number
39
+ readonly tokensBefore: number
40
+ readonly tokensAfter: number
41
+ }
42
+
43
+ export interface BenefitInput {
44
+ /** Cache-hit discount rate α ∈ (0,1); validated upstream by config parsing. */
45
+ readonly alpha: number
46
+ /** Token mass of the protected tail that must be refilled after a mutation. */
47
+ readonly tailTokens: number
48
+ /** Estimated remaining turns Ŝ; `undefined` keeps expectedSaving out of the result. */
49
+ readonly remainingTurns?: number | undefined
50
+ /** True for fresh-stage batches: their content was never served, so it is
51
+ * not in the KV cache and shaping it causes no cache break — no refill
52
+ * penalty applies and the whole discounted recovery is pure gain. */
53
+ readonly refillPenaltyExempt?: boolean | undefined
54
+ }
55
+
56
+ export interface BenefitEstimate {
57
+ /** Net reclaimed tokens across the batch; may be ≤ 0 when a batch is not worth it. */
58
+ readonly recoveredTokens: number
59
+ /** The one-time cache-refill penalty the merged mutation pays: (1−α)·tailTokens. */
60
+ readonly penaltyTokens: number
61
+ /** Turns of discounted recovery needed to recoup the penalty; `undefined` when α·R ≤ 0. */
62
+ readonly paybackTurns?: number
63
+ /** Discounted net benefit over the remaining session; omitted when Ŝ is unknown. */
64
+ readonly expectedSaving?: number
65
+ }
66
+
67
+ /**
68
+ * The band one priced batch falls into. Advisory vocabulary only — every band
69
+ * lands; the label says what the model thought of the landing, not whether it
70
+ * was allowed to happen.
71
+ */
72
+ export type AdviceBand =
73
+ /** Payback ≤ 1 turn, or ≤ a quarter of the estimated remaining turns. */
74
+ | 'profitable'
75
+ /** At least one candidate reaches the high-impact threshold: the batch is
76
+ * large enough that a human would want to know it moved. */
77
+ | 'high-impact'
78
+ /** Ŝ known and payback ∈ (1, 3]: it does pay back, but slowly. */
79
+ | 'slow-payback'
80
+ /** α·R ≤ 0: the accounting has no discounted recovery to argue from. */
81
+ | 'unpriceable'
82
+ /** Ŝ known and payback > 3 turns: the model would not have spent the cache break. */
83
+ | 'not-worth-it'
84
+
85
+ export interface AdviceInput {
86
+ /** Cache-hit discount rate α ∈ (0,1); validated upstream by config parsing. */
87
+ readonly alpha: number
88
+ /** Token mass of the protected tail that must be refilled after a mutation. */
89
+ readonly tailTokens: number
90
+ /** Candidates at or above this token impact are labelled `high-impact`. */
91
+ readonly highImpactTokens: number
92
+ /** Estimated remaining turns Ŝ; `undefined` closes the slow-payback band. */
93
+ readonly remainingTurns?: number | undefined
94
+ /** Landing stage of the batch: `'fresh'` batches are priced without the
95
+ * tail-refill penalty (first-exposure shaping causes no cache break);
96
+ * `'history'` batches — already-served content — pay it in full. */
97
+ readonly stage?: 'fresh' | 'history' | undefined
98
+ }
99
+
100
+ export interface AdviceResult {
101
+ readonly band: AdviceBand
102
+ /** The full benefit estimate the band was derived from. */
103
+ readonly benefit: BenefitEstimate
104
+ /** Number of candidates that carried a positive recovery and were priced. */
105
+ readonly priced: number
106
+ /** Largest single-candidate token mass in the batch (the high-impact evidence). */
107
+ readonly maxTokensBefore: number
108
+ }
109
+
110
+ /**
111
+ * Shipped defaults of the advisory model. They are constants rather than
112
+ * settings keys because the machine no longer acts on them: after the review
113
+ * gate was retired these numbers only shape a label, so exposing them as
114
+ * tunable configuration would advertise a control that changes no behavior.
115
+ */
116
+ export const DEFAULT_ADVICE_ALPHA = 0.1
117
+ export const DEFAULT_ADVICE_HIGH_IMPACT_TOKENS = 4_000
118
+
119
+ /**
120
+ * Aggregate the batch-level benefit of a set of reduction candidates.
121
+ *
122
+ * Individual candidates whose replacement would grow the context contribute
123
+ * zero recovery (they never make a batch look better than dropping them).
124
+ */
125
+ export function computeBenefit(candidates: readonly BenefitCandidate[], input: BenefitInput): BenefitEstimate {
126
+ const { alpha, tailTokens, remainingTurns } = input
127
+ let recoveredTokens = 0
128
+ for (const candidate of candidates) {
129
+ recoveredTokens += Math.max(0, candidate.tokensBefore - candidate.tokensAfter)
130
+ }
131
+ const penaltyTokens = input.refillPenaltyExempt === true ? 0 : (1 - alpha) * tailTokens
132
+ const perTurnSaving = alpha * recoveredTokens
133
+ if (perTurnSaving <= 0) {
134
+ return remainingTurns === undefined
135
+ ? { recoveredTokens, penaltyTokens }
136
+ : { recoveredTokens, penaltyTokens, expectedSaving: -penaltyTokens }
137
+ }
138
+ const paybackTurns = penaltyTokens / perTurnSaving
139
+ if (remainingTurns === undefined) {
140
+ return { recoveredTokens, penaltyTokens, paybackTurns }
141
+ }
142
+ return {
143
+ recoveredTokens,
144
+ penaltyTokens,
145
+ paybackTurns,
146
+ expectedSaving: perTurnSaving * Math.max(0, remainingTurns - paybackTurns),
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Label one batch of planned replacements.
152
+ *
153
+ * Pipeline: zero/negative-recovery candidates are priced out first (they never
154
+ * make a batch look better), the surviving batch is priced once through
155
+ * `computeBenefit`, and the band is a batch decision — the refill penalty is a
156
+ * property of the landing event, not of any single candidate, so pricing per
157
+ * candidate would overstate payback N-fold.
158
+ *
159
+ * Band precedence (identical thresholds to the retired triage model):
160
+ * - α too small to price a payback → `unpriceable`;
161
+ * - any candidate at `highImpactTokens` → `high-impact`;
162
+ * - `paybackTurns ≤ 1`, or Ŝ known and `paybackTurns ≤ 0.25·Ŝ` → `profitable`;
163
+ * - Ŝ known and `paybackTurns ∈ (1, 3]` → `slow-payback`;
164
+ * - everything else → `not-worth-it`.
165
+ *
166
+ * @param candidates - planned replacements of one pass, in any order.
167
+ * @param input - pricing inputs and the stage of the batch.
168
+ * @returns the advice, or `undefined` when nothing carried a positive recovery.
169
+ */
170
+ export function adviseCandidates(
171
+ candidates: readonly BenefitCandidate[],
172
+ input: AdviceInput,
173
+ ): AdviceResult | undefined {
174
+ const usable: BenefitCandidate[] = []
175
+ for (const candidate of candidates) {
176
+ if (Math.max(0, candidate.tokensBefore - candidate.tokensAfter) <= 0) continue
177
+ usable.push(candidate)
178
+ }
179
+ if (usable.length === 0) return undefined
180
+
181
+ const benefit = computeBenefit(usable, {
182
+ alpha: input.alpha,
183
+ tailTokens: input.tailTokens,
184
+ ...input.remainingTurns !== undefined ? { remainingTurns: input.remainingTurns } : {},
185
+ refillPenaltyExempt: input.stage === 'fresh',
186
+ })
187
+ const payback = benefit.paybackTurns
188
+ const maxTokensBefore = usable.reduce((max, candidate) => Math.max(max, candidate.tokensBefore), 0)
189
+ const band: AdviceBand = payback === undefined
190
+ ? 'unpriceable'
191
+ : maxTokensBefore >= input.highImpactTokens
192
+ ? 'high-impact'
193
+ : payback <= 1
194
+ || (input.remainingTurns !== undefined && payback <= 0.25 * input.remainingTurns)
195
+ ? 'profitable'
196
+ : input.remainingTurns !== undefined && payback <= 3
197
+ ? 'slow-payback'
198
+ : 'not-worth-it'
199
+ return { band, benefit, priced: usable.length, maxTokensBefore }
200
+ }
@@ -85,18 +85,6 @@ export interface PresetOptions {
85
85
  readonly sampleLimit: number
86
86
  readonly minTokens: number
87
87
  }
88
- /**
89
- * Human-gated review pipeline (beta): edge/high-impact candidates queue for
90
- * manual approval and execute in one merged batch at the next turn boundary
91
- * instead of the automatic path (R4).
92
- */
93
- readonly reviewMode: boolean
94
- /** Turn-boundary patience: pending review proposals older than this many turns auto-expire (R4). */
95
- readonly reviewTimeoutTurns: number
96
- /** Cache-hit discount rate α in the benefit model; expectedSaving = α·R·Ŝ − (1−α)·tail. */
97
- readonly cacheHitDiscountAlpha: number
98
- /** Candidates whose tokenBefore reaches this threshold bypass payback triage and always enter review (R4). */
99
- readonly reviewHighImpactTokens: number
100
88
  }
101
89
 
102
90
  /** Common user-authored Custom stages shared by persisted policy versions. */
@@ -154,11 +142,6 @@ export interface PresetOptionsSettings {
154
142
  readonly prefixStabilizer?: boolean
155
143
  readonly readState?: boolean
156
144
  readonly estimatorMode?: '' | 'host' | 'direct'
157
- /** Review-mode overrides (beta); see PresetOptions.reviewMode. */
158
- readonly reviewMode?: boolean
159
- readonly reviewTimeoutTurns?: number
160
- readonly cacheHitDiscountAlpha?: number
161
- readonly reviewHighImpactTokens?: number
162
145
  /**
163
146
  * Estimator endpoint fields. Persisted-settings only: they never enter the
164
147
  * frozen CompressionPolicy, which is emitted verbatim by policy-resolved