pi-midcompact 0.5.3 → 0.7.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.
- package/README.md +27 -10
- package/README.zh-CN.md +16 -1
- package/package.json +4 -2
- package/skills/midcompact/SKILL.md +53 -86
- package/skills/midcompact/references/tool-interface.md +41 -59
- package/src/SPEC.md +35 -7
- package/src/content-metrics.ts +75 -3
- package/src/index.ts +232 -118
- package/src/inventory.ts +2 -2
- package/src/plan.ts +10 -10
- package/src/projection.ts +12 -3
- package/src/review-ui.ts +2 -2
- package/src/review-webui.html +837 -481
- package/src/review-webui.ts +150 -57
- package/src/selection-ui.ts +1 -1
- package/src/start-ui.ts +2 -2
- package/src/telemetry.ts +1 -1
package/src/content-metrics.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
// Sole owner of
|
|
2
|
-
//
|
|
3
|
-
//
|
|
1
|
+
// Sole owner of message content statistics. Factual char/image counts are the
|
|
2
|
+
// authority; the only token conversion allowed is the explicitly scoped,
|
|
3
|
+
// display-level estimator at the bottom of this file (web UI presentation
|
|
4
|
+
// only — it never gates decisions, commits, or range validity). Image base64
|
|
5
|
+
// never contributes to text char counts.
|
|
4
6
|
|
|
5
7
|
import type { ContentMetrics, ImageFact, MessageLike } from "./types.js";
|
|
6
8
|
|
|
@@ -183,3 +185,73 @@ export function aggregateMetrics(parts: readonly ContentMetrics[]): ContentMetri
|
|
|
183
185
|
}
|
|
184
186
|
return { contentChars, imageCount, images };
|
|
185
187
|
}
|
|
188
|
+
|
|
189
|
+
// ---- Display-level token estimation (web UI presentation only) ----
|
|
190
|
+
//
|
|
191
|
+
// The web UI shows a projected post-commit usage band. Because the consumer
|
|
192
|
+
// model is provider-dependent, tokens are estimated from char classes with a
|
|
193
|
+
// documented assumption table instead of a real tokenizer: the [low, high]
|
|
194
|
+
// pairs express published tokenizer spread and are propagated as a band, never
|
|
195
|
+
// collapsed into a single authoritative number. The band is derived from the
|
|
196
|
+
// content mix of the atoms involved (ASCII-heavy content lands near the tight
|
|
197
|
+
// end, CJK-heavy near the wide end). Nothing here feeds commit gating, range
|
|
198
|
+
// validation, or any decision.
|
|
199
|
+
|
|
200
|
+
/** Per-char-class token-cost assumptions: [low, high] tokens per char. */
|
|
201
|
+
export const TOKEN_ESTIMATE = {
|
|
202
|
+
/** ASCII/code: roughly 3.3–4.5 chars per token across common tokenizers. */
|
|
203
|
+
narrowTokPerChar: [0.22, 0.3],
|
|
204
|
+
/** Non-ASCII scripts (CJK, kana, hangul, emoji, …): the dominant spread. */
|
|
205
|
+
wideTokPerChar: [0.5, 1.0],
|
|
206
|
+
/** Images: provider- and resolution-dependent flat allowance. */
|
|
207
|
+
imageTok: [700, 1600],
|
|
208
|
+
} as const;
|
|
209
|
+
|
|
210
|
+
/** Char classes the estimator distinguishes. */
|
|
211
|
+
export interface CharMix {
|
|
212
|
+
/** ASCII code points. */
|
|
213
|
+
narrowChars: number;
|
|
214
|
+
/** Everything non-ASCII (counted conservatively at the wide rate). */
|
|
215
|
+
wideChars: number;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Classification is deliberately coarse: ASCII is estimated at the narrow
|
|
219
|
+
// rate; every non-ASCII code point (CJK, kana, hangul, emoji, Cyrillic, …) is
|
|
220
|
+
// counted at the wide rate, which is the conservative side for CJK-heavy
|
|
221
|
+
// content and keeps the table honest without per-script modeling.
|
|
222
|
+
|
|
223
|
+
/** Split a text into narrow (ASCII) and wide (everything else) code points. */
|
|
224
|
+
export function charClassCounts(text: string): CharMix {
|
|
225
|
+
let narrowChars = 0;
|
|
226
|
+
let wideChars = 0;
|
|
227
|
+
for (const ch of text) {
|
|
228
|
+
const cp = ch.codePointAt(0)!;
|
|
229
|
+
if (cp <= 0x7f) {
|
|
230
|
+
narrowChars += 1;
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
wideChars += 1;
|
|
234
|
+
}
|
|
235
|
+
return { narrowChars, wideChars };
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export interface TokenEstimate {
|
|
239
|
+
point: number;
|
|
240
|
+
low: number;
|
|
241
|
+
high: number;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/** Estimate tokens for a char mix plus images, as a propagated band. */
|
|
245
|
+
export function estimateTokens(mix: CharMix, imageCount: number): TokenEstimate {
|
|
246
|
+
const [aLo, aHi] = TOKEN_ESTIMATE.narrowTokPerChar;
|
|
247
|
+
const [cLo, cHi] = TOKEN_ESTIMATE.wideTokPerChar;
|
|
248
|
+
const [iLo, iHi] = TOKEN_ESTIMATE.imageTok;
|
|
249
|
+
const mid = (lo: number, hi: number) => (lo + hi) / 2;
|
|
250
|
+
return {
|
|
251
|
+
point: Math.round(mix.narrowChars * mid(aLo, aHi)
|
|
252
|
+
+ mix.wideChars * mid(cLo, cHi)
|
|
253
|
+
+ imageCount * mid(iLo, iHi)),
|
|
254
|
+
low: Math.round(mix.narrowChars * aLo + mix.wideChars * cLo + imageCount * iLo),
|
|
255
|
+
high: Math.round(mix.narrowChars * aHi + mix.wideChars * cHi + imageCount * iHi),
|
|
256
|
+
};
|
|
257
|
+
}
|