pi-ptc-meter 1.0.30 → 1.0.32
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/index.ts +2 -36
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -87,6 +87,7 @@ export function median(xs: number[]): number {
|
|
|
87
87
|
if (!xs.length) return 0;
|
|
88
88
|
const s = [...xs].sort((a, b) => a - b);
|
|
89
89
|
const m = Math.floor(s.length / 2);
|
|
90
|
+
// 偶数长度取整到整数毫秒:该值只用于展示(ms / 次数),保留小数无意义
|
|
90
91
|
return s.length % 2 ? s[m] : Math.round((s[m - 1] + s[m]) / 2);
|
|
91
92
|
}
|
|
92
93
|
|
|
@@ -198,45 +199,10 @@ function statsLine(th: number, med: number, rows: Row[]): string {
|
|
|
198
199
|
const parts: string[] = [`上一轮 ${last} 次工具调用`];
|
|
199
200
|
if (secs !== null) {
|
|
200
201
|
parts.push(`实际 ${secs}s`);
|
|
201
|
-
if (lastTurnHit !== null) parts.push(`命中 ${lastTurnHit}
|
|
202
|
-
if (lastTurnEstCalls !== null && lastTurnEstCalls > 0) {
|
|
203
|
-
const dc = Math.round(((last - lastTurnEstCalls) / lastTurnEstCalls) * 100);
|
|
204
|
-
parts.push(`预计 ${lastTurnEstCalls} 次 / 实际 ${last} 次(偏差 ${dc >= 0 ? "+" : ""}${dc}%)`);
|
|
205
|
-
}
|
|
206
|
-
if (lastTurnEst !== null) {
|
|
207
|
-
const dev = Math.round(((lastTurnMs / 1000 - lastTurnEst) / lastTurnEst) * 100);
|
|
208
|
-
parts.push(`预计 ${lastTurnEst}s / 实际 ${secs}s(偏差 ${dev >= 0 ? "+" : ""}${dev}%)`);
|
|
209
|
-
} else {
|
|
210
|
-
const base = Math.round(median(rows.map((r) => r.ms)) / 1000);
|
|
211
|
-
// 借鉴 think-anchor 的自适应:声明率已高时不再每轮催(实测 88.9% 声明率下这句话是纯噪音)
|
|
212
|
-
const declRate = rows.length ? rows.filter((r) => typeof r.estCalls === "number" && (r.estCalls as number) > 0).length / rows.length : 0;
|
|
213
|
-
const nudge = declRate < 0.6 ? " → 本轮开工前先报「预计 N 次」" : "";
|
|
214
|
-
parts.push((base > 0 ? "预计未声明(同类中位 " + base + "s)" : "预计未声明") + nudge);
|
|
215
|
-
}
|
|
202
|
+
if (lastTurnHit !== null && lastTurnHit < 90) parts.push(`命中 ${lastTurnHit}%(低)`);
|
|
216
203
|
}
|
|
217
204
|
// 校正指引(回路自动纠偏):近若干轮系统性偏离时,直接给出本轮该报的倍数——不靠自觉。
|
|
218
|
-
// 调用数校正:次数由任务类型决定,方差远小于时长——优先用它给指引。
|
|
219
205
|
try {
|
|
220
|
-
const ecRows = rows.filter((r) => typeof r.estCalls === "number" && (r.estCalls as number) > 0);
|
|
221
|
-
if (ecRows.length >= 3) {
|
|
222
|
-
const dcs = ecRows.map((r) => ((r.calls - (r.estCalls as number)) / (r.estCalls as number)) * 100);
|
|
223
|
-
const mdc = median(dcs);
|
|
224
|
-
if (mdc <= -20 || mdc >= 20) {
|
|
225
|
-
const f = Math.min(3, Math.max(0.2, Math.round((1 + mdc / 100) * 100) / 100)); // 夹在 0.2–3:极端中位(声明失真)不放大成荒谬倍数
|
|
226
|
-
parts.push(`近 ${ecRows.length} 轮调用数系统性${mdc < 0 ? "高估" : "低估"}(中位 ${mdc > 0 ? "+" : ""}${Math.round(mdc)}%)→ 本轮按约 ${f} 倍报`);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
} catch { /* 静默 */ }
|
|
230
|
-
try {
|
|
231
|
-
const estRows = rows.filter((r) => typeof r.est === "number" && (r.est as number) > 0);
|
|
232
|
-
if (estRows.length >= 3) {
|
|
233
|
-
const devs = estRows.map((r) => ((r.ms / 1000) - (r.est as number)) / (r.est as number) * 100);
|
|
234
|
-
const md = median(devs);
|
|
235
|
-
if (md <= -20 || md >= 20) {
|
|
236
|
-
const factor = Math.min(3, Math.max(0.2, Math.round((1 + md / 100) * 100) / 100));
|
|
237
|
-
parts.push(`近 ${estRows.length} 轮耗时系统性${md < 0 ? "高估" : "低估"}(中位 ${md > 0 ? "+" : ""}${Math.round(md)}%)→ 本轮按约 ${factor} 倍报`);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
206
|
} catch { /* 指引失败不影响统计行 */ }
|
|
241
207
|
const verdict = last >= th
|
|
242
208
|
? `超阈值 ${th} · 判据 = 本轮计数不超阈值且无同类调用可并(可并性人工复核)`
|