maxpool 1.8.1 → 1.8.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.
- package/package.json +1 -1
- package/src/account-manager.js +14 -13
- package/src/capacity-ledger.js +19 -2
package/package.json
CHANGED
package/src/account-manager.js
CHANGED
|
@@ -3055,19 +3055,20 @@ export class AccountManager {
|
|
|
3055
3055
|
* covers the case where the old stamp was never learned. */
|
|
3056
3056
|
noteCapacityWindowAdvance(accountName, window, prevResetAt, nextResetAt) {
|
|
3057
3057
|
if (!prevResetAt || !nextResetAt) return;
|
|
3058
|
-
//
|
|
3059
|
-
//
|
|
3060
|
-
//
|
|
3061
|
-
//
|
|
3062
|
-
//
|
|
3063
|
-
//
|
|
3064
|
-
//
|
|
3065
|
-
//
|
|
3066
|
-
// (>=5h)
|
|
3067
|
-
//
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3058
|
+
// TWO guards, both learned from live data (2026-08-23):
|
|
3059
|
+
// 1. PAST stamp = a probe that answered late (its window rolled mid-request) or
|
|
3060
|
+
// vendor clock skew — honoring it closed a minutes-long "cycle" sliver. Close
|
|
3061
|
+
// at NOW instead: the window genuinely rolled, just later than the stale stamp.
|
|
3062
|
+
// 2. JITTER: OAuth stamps derive per-response as Date.now()+delay*1000
|
|
3063
|
+
// (parseResetHeader), so one boundary reads ~2s later on every response; a
|
|
3064
|
+
// bare `>` comparison shredded one real 5h window into 9-10 fake cycles and
|
|
3065
|
+
// dated a "weekly" cycle a week into the future. A real advance moves a whole
|
|
3066
|
+
// window (>=5h) — the 60s epsilon separates it by three orders of magnitude.
|
|
3067
|
+
// Provider stamps (z.ai/Kimi probe) are absolute and never jitter.
|
|
3068
|
+
const nowMs = Date.now();
|
|
3069
|
+
const boundary = nextResetAt <= nowMs ? nowMs : nextResetAt;
|
|
3070
|
+
if (boundary - prevResetAt < WINDOW_ADVANCE_EPSILON_MS) return;
|
|
3071
|
+
this.capacity.closeCycle(accountName, window, boundary, { resetAt: prevResetAt });
|
|
3071
3072
|
}
|
|
3072
3073
|
|
|
3073
3074
|
/**
|
package/src/capacity-ledger.js
CHANGED
|
@@ -32,13 +32,24 @@ export class CapacityLedger {
|
|
|
32
32
|
this._now = now;
|
|
33
33
|
// accountName → { ses: {open?, closed: []}, wk: {open?, closed: []}, days: {utcDay: {tokens, partial}} }
|
|
34
34
|
this._accounts = new Map();
|
|
35
|
+
// True only for a ledger restored with no usable history — see fromSerialized.
|
|
36
|
+
// Cleared per account+window once that window's first boundary is behind us.
|
|
37
|
+
this._joinedMidWindow = false;
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
/** Restore from a serialized payload (state.json). Tolerant: unknown schemaVersion →
|
|
38
41
|
* start empty and KEEP the file (the caller preserves it); a corrupt shape → empty. */
|
|
39
42
|
static fromSerialized(payload, { now = () => Date.now() } = {}) {
|
|
40
43
|
const l = new CapacityLedger({ now });
|
|
41
|
-
if (!payload || payload.schemaVersion !== SCHEMA_VERSION)
|
|
44
|
+
if (!payload || payload.schemaVersion !== SCHEMA_VERSION) {
|
|
45
|
+
// No history to continue: whatever window each account is in RIGHT NOW is
|
|
46
|
+
// already in progress, so the next cycle we close saw only its tail. Flag it so
|
|
47
|
+
// it is shown but never averaged (live 2026-08-23: the first GLM cycle after the
|
|
48
|
+
// v1.8.1 migration read 21,192 tokens for a 5h window it had watched 14.6 min —
|
|
49
|
+
// and with one cycle recorded, that sliver WAS every column).
|
|
50
|
+
l._joinedMidWindow = true;
|
|
51
|
+
return l;
|
|
52
|
+
}
|
|
42
53
|
try {
|
|
43
54
|
for (const [name, rec] of Object.entries(payload.accounts || {})) {
|
|
44
55
|
const a = { ses: { open: null, closed: [] }, wk: { open: null, closed: [] }, days: {} };
|
|
@@ -91,7 +102,12 @@ export class CapacityLedger {
|
|
|
91
102
|
// reset stamp was never learned). startedAt is the accrual time then — the cycle
|
|
92
103
|
// will be flagged partial by the caller if the boot gap warrants it (B1/B2).
|
|
93
104
|
if (!rec[w].open) {
|
|
94
|
-
rec[w].
|
|
105
|
+
const joined = this._joinedMidWindow && rec[w].closed.length === 0;
|
|
106
|
+
rec[w].open = {
|
|
107
|
+
startedAt: at, tokensSoFar: 0, lastAccrualAt: at,
|
|
108
|
+
complete: !joined, disabledDuring: false,
|
|
109
|
+
...(joined ? { partialReason: 'joined-mid-window' } : {}),
|
|
110
|
+
};
|
|
95
111
|
}
|
|
96
112
|
rec[w].open.tokensSoFar += input + output;
|
|
97
113
|
rec[w].open.lastAccrualAt = at;
|
|
@@ -162,6 +178,7 @@ export class CapacityLedger {
|
|
|
162
178
|
tokens: open.tokensSoFar,
|
|
163
179
|
complete: open.complete,
|
|
164
180
|
disabledDuring: open.disabledDuring,
|
|
181
|
+
...(open.partialReason ? { partialReason: open.partialReason } : {}),
|
|
165
182
|
resetAt,
|
|
166
183
|
});
|
|
167
184
|
if (rec[window].closed.length > MAX_CYCLES_PER_WINDOW) rec[window].closed.shift();
|