pi-ptc-meter 1.0.35 → 1.0.36
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 +2 -2
- package/index.ts +11 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ pi install npm:pi-ptc-meter
|
|
|
33
33
|
|
|
34
34
|
| 键 | 默认 | 说明 |
|
|
35
35
|
| --- | --- | --- |
|
|
36
|
-
| `threshold` |
|
|
36
|
+
| `threshold` | 自适应 | 每轮调用数阈值:未显式配置时 = max(3, 2.5× 最近 40 轮中位);显式配置则用配置值 |
|
|
37
37
|
| `inject` | `true` | 是否注入回灌消息 |
|
|
38
38
|
| `notify` | `false` | 改用弹窗提示 |
|
|
39
39
|
|
|
@@ -148,7 +148,7 @@ Config file `~/.pi/ptc-meter.json` (optional; invalid JSON falls back):
|
|
|
148
148
|
|
|
149
149
|
| Key | Default | Description |
|
|
150
150
|
| --- | --- | --- |
|
|
151
|
-
| `threshold` |
|
|
151
|
+
| `threshold` | adaptive | Per-turn call threshold: when unset = max(3, 2.5x median of the last 40 turns; an explicit value wins |
|
|
152
152
|
| `inject` | `true` | Enable the feedback message |
|
|
153
153
|
| `notify` | `false` | Use UI notifications instead |
|
|
154
154
|
|
package/index.ts
CHANGED
|
@@ -58,9 +58,17 @@ function loadConf(): Conf {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
/** 生效阈值(配置无值或非法时回退默认)。 */
|
|
61
|
+
/** 生效阈值:显式配置优先;否则自适应 2.5× 最近窗口中位。 */
|
|
62
|
+
// 固定阈值在短任务会话里永不触发(2026-10-18 实测:本会话中位 6、阈值 50 → 0/60 轮)。
|
|
63
|
+
// 4398 轮回测:固定 50 触发 16.7%(短会话 0),2.5×中位 触发 13.1%(长短会话都能触发)。
|
|
61
64
|
function threshold(): number {
|
|
62
65
|
const c = loadConf();
|
|
63
|
-
|
|
66
|
+
if (typeof c.threshold === "number" && c.threshold > 0) return c.threshold;
|
|
67
|
+
try {
|
|
68
|
+
const cs = recentRows(TAIL, "").map((r) => r.calls).filter((x) => typeof x === "number" && x >= 0);
|
|
69
|
+
if (cs.length >= 10) return Math.max(3, Math.round(2.5 * median(cs)));
|
|
70
|
+
} catch { /* 回退默认 */ }
|
|
71
|
+
return DEFAULT_THRESHOLD;
|
|
64
72
|
}
|
|
65
73
|
|
|
66
74
|
// 轮内计数(反馈回路:随注入回到上下文,见 before_agent_start)
|
|
@@ -134,7 +142,7 @@ function recentRows(n: number, sid: string): Row[] {
|
|
|
134
142
|
try {
|
|
135
143
|
const j = JSON.parse(r) as { calls?: number; ms?: number; est?: number | null; estCalls?: number | null; sid?: string };
|
|
136
144
|
const jsid = (j.sid ?? "").toLowerCase().replace(/\.jsonl$/, "");
|
|
137
|
-
if (jsid !== sid) return null; // 会话不符或无 sid 旧记录:不进统计(sid 已规范化,跨重启/带后缀的历史行可合并)
|
|
145
|
+
if (sid && jsid !== sid) return null; // 空 sid = 跨会话(阈值自适应用) // 会话不符或无 sid 旧记录:不进统计(sid 已规范化,跨重启/带后缀的历史行可合并)
|
|
138
146
|
return { calls: j.calls ?? 0, ms: typeof j.ms === "number" ? j.ms : 0, est: typeof j.est === "number" ? j.est : null, estCalls: typeof j.estCalls === "number" ? j.estCalls : null };
|
|
139
147
|
} catch { return null; }
|
|
140
148
|
})
|
|
@@ -166,7 +174,7 @@ const EST_RE = /(?:预计|预估|eta)[^0-9\n]{0,8}(\d+(?:\.\d+)?)\s*(秒|s(?!\w)
|
|
|
166
174
|
/** 从我的回复文本里解析预计耗时(秒);无声明或非法值返回 null。 */
|
|
167
175
|
function parseEstimate(text: string): number | null {
|
|
168
176
|
try {
|
|
169
|
-
// 扫**尾部窗口**:声明写在回复末尾;前 6000 字符从未覆盖到它(实测 est
|
|
177
|
+
// 扫**尾部窗口**:声明写在回复末尾;前 6000 字符从未覆盖到它(实测 est 填充率仅 1.5%)
|
|
170
178
|
// 取最后一个匹配 = 末尾的声明(同时谈格式时,正文中部的不算,因窗口在尾部)
|
|
171
179
|
const m = [...text.slice(-15000).matchAll(new RegExp(EST_RE.source, "gi"))].pop();
|
|
172
180
|
if (!m) return null;
|