maxpool 1.5.45 → 1.5.46
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/server.js +12 -18
- package/src/tui.js +46 -5
package/package.json
CHANGED
package/src/server.js
CHANGED
|
@@ -1334,7 +1334,7 @@ function isContextLengthError(errorBody) {
|
|
|
1334
1334
|
return /exceeded model token limit|maximum context length|context length exceeded|context window (?:size )?(?:exceeded|too)|prompt is too long|input is too long|reduce the length of|too many (?:input )?tokens|request too large/i.test(errorBody);
|
|
1335
1335
|
}
|
|
1336
1336
|
|
|
1337
|
-
export const __serverTest = { unavailableMessage, computeQueueWindowMs, isRetriableUpstreamStatus, isCapacitySignalStatus,
|
|
1337
|
+
export const __serverTest = { unavailableMessage, computeQueueWindowMs, isRetriableUpstreamStatus, isCapacitySignalStatus, isStrippableThinkingBlock, stripForeignThinkingBlocks, headerValue, getMaxpoolProfile, ensureQueueHeartbeat, clearQueueHeartbeat, commitStreamGraceHeartbeat, describeRequest, classifyRateLimit, detectTranscriptOrigin, isAnthropicIncompatBody, isContextLengthError, streamResponse, startIdleRequestReaper };
|
|
1338
1338
|
|
|
1339
1339
|
async function readErrorBody(upstreamRes, limitBytes = 64 * 1024) {
|
|
1340
1340
|
if (!upstreamRes.body) return '';
|
|
@@ -1510,17 +1510,16 @@ function secondsUntilParsedTime(value) {
|
|
|
1510
1510
|
return null;
|
|
1511
1511
|
}
|
|
1512
1512
|
|
|
1513
|
-
//
|
|
1514
|
-
//
|
|
1515
|
-
// digest
|
|
1516
|
-
//
|
|
1517
|
-
//
|
|
1518
|
-
//
|
|
1519
|
-
//
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
return /^[0-9a-f]+$/i.test(sig);
|
|
1513
|
+
// Provider thinking signatures CANNOT be told apart from Anthropic's by shape — measured
|
|
1514
|
+
// against the live APIs 2026-07-25: Anthropic ~200-400 char base64, GLM a 24-char hex
|
|
1515
|
+
// digest, Kimi(K3) a 12,946-char base64 blob. A shape heuristic tuned to GLM silently
|
|
1516
|
+
// missed Kimi entirely. So the repair below does NOT guess: it strips EVERY `thinking`
|
|
1517
|
+
// block. That is safe precisely because it only ever runs in response to Anthropic's own
|
|
1518
|
+
// signature-rejection 400 — a healthy Claude-only session never reaches it — and a history
|
|
1519
|
+
// with thinking removed is accepted (200 OK, verified, incl. tool_use → tool_result).
|
|
1520
|
+
// `redacted_thinking` is never touched: it legitimately carries `data` and no signature.
|
|
1521
|
+
function isStrippableThinkingBlock(block) {
|
|
1522
|
+
return block?.type === 'thinking';
|
|
1524
1523
|
}
|
|
1525
1524
|
|
|
1526
1525
|
/**
|
|
@@ -1546,12 +1545,7 @@ function stripForeignThinkingBlocks(body) {
|
|
|
1546
1545
|
if (msg?.role !== 'assistant' || !Array.isArray(msg.content)) { messages.push(msg); continue; }
|
|
1547
1546
|
let localRemoved = 0;
|
|
1548
1547
|
const kept = msg.content.filter(block => {
|
|
1549
|
-
|
|
1550
|
-
// legitimately has NO signature, so signature-based judging would strip 100% of
|
|
1551
|
-
// them (verified against the live API). GLM's contamination is always a
|
|
1552
|
-
// `thinking` block with a hex signature.
|
|
1553
|
-
if (block?.type !== 'thinking') return true;
|
|
1554
|
-
if (!isForeignThinkingSignature(block.signature)) return true;
|
|
1548
|
+
if (!isStrippableThinkingBlock(block)) return true;
|
|
1555
1549
|
localRemoved++;
|
|
1556
1550
|
return false;
|
|
1557
1551
|
});
|
package/src/tui.js
CHANGED
|
@@ -253,6 +253,7 @@ export class TUI {
|
|
|
253
253
|
// Set by index.js after construction (a deferred closure, not a constructor literal —
|
|
254
254
|
// avoids the const TDZ on applyUpdateIfReady, which is defined after `new TUI`).
|
|
255
255
|
this.checkNow = null;
|
|
256
|
+
this.updateBusy = null; // live progress text while an update check/apply runs
|
|
256
257
|
|
|
257
258
|
this.log = []; // completed activity entries
|
|
258
259
|
this.active = new Map(); // in-flight requests
|
|
@@ -456,10 +457,20 @@ export class TUI {
|
|
|
456
457
|
_keyUpdates(k) {
|
|
457
458
|
if (k === 'c') {
|
|
458
459
|
// Check & apply now — the dance-killer: pull the latest + seamless-reload in place,
|
|
459
|
-
// no quit/relaunch.
|
|
460
|
-
|
|
461
|
-
if (this.checkNow) this.
|
|
462
|
-
|
|
460
|
+
// no quit/relaunch. STAY on this screen and show live progress: bouncing straight
|
|
461
|
+
// back to the dashboard was indistinguishable from "nothing happened".
|
|
462
|
+
if (!this.checkNow) { this._addLog('Update check unavailable on this worker'); return; }
|
|
463
|
+
if (this.updateBusy) return; // already running
|
|
464
|
+
this.updateBusy = 'Checking npm…';
|
|
465
|
+
this.render();
|
|
466
|
+
Promise.resolve(this.checkNow())
|
|
467
|
+
.catch(() => {})
|
|
468
|
+
.finally(() => {
|
|
469
|
+
// If an update was found+applied, the seamless reload replaces this worker and
|
|
470
|
+
// this never renders. Otherwise report the outcome in place.
|
|
471
|
+
this.updateBusy = null;
|
|
472
|
+
if (this.mode === 'updates') this.render();
|
|
473
|
+
});
|
|
463
474
|
} else if (k === 't') {
|
|
464
475
|
this._toggleAutoUpdate();
|
|
465
476
|
} else if (k === 'esc' || k === 'q') {
|
|
@@ -467,6 +478,29 @@ export class TUI {
|
|
|
467
478
|
}
|
|
468
479
|
}
|
|
469
480
|
|
|
481
|
+
/** The visible Updates panel. Answers, at a glance: what am I running, is anything
|
|
482
|
+
* newer, is it automatic, and what is happening right now. */
|
|
483
|
+
_renderUpdatesDetail() {
|
|
484
|
+
const v = this.am.versionInfo;
|
|
485
|
+
const running = v?.current ? `v${v.current}` : 'unknown';
|
|
486
|
+
const auto = this._autoUpdateOn();
|
|
487
|
+
const out = [];
|
|
488
|
+
out.push(` ${bold('Updates')}`);
|
|
489
|
+
if (!v) {
|
|
490
|
+
out.push(` ${dim('Running')} ${running} ${dim('· checking npm for a newer version…')}`);
|
|
491
|
+
} else if (v.hasUpdate && v.latest) {
|
|
492
|
+
out.push(` ${dim('Running')} ${running} ${yellow(`v${v.latest} is available`)}`);
|
|
493
|
+
out.push(auto
|
|
494
|
+
? ` ${dim('It installs itself automatically. Press')} ${bold('c')} ${dim('to get it right now.')}`
|
|
495
|
+
: ` ${dim('Automatic updates are off. Press')} ${bold('c')} ${dim('to install it now, or')} ${bold('t')} ${dim('to turn automatic on.')}`);
|
|
496
|
+
} else {
|
|
497
|
+
out.push(` ${dim('Running')} ${running} ${green('up to date')}`);
|
|
498
|
+
out.push(` ${dim(auto ? 'New versions install themselves.' : 'Automatic updates are off — press t to turn them on.')}`);
|
|
499
|
+
}
|
|
500
|
+
if (this.updateBusy) out.push(` ${cyan(SPINNER[this.frame])} ${dim(this.updateBusy)}`);
|
|
501
|
+
return out;
|
|
502
|
+
}
|
|
503
|
+
|
|
470
504
|
async _toggleAutoUpdate() {
|
|
471
505
|
const turnOn = !this._autoUpdateOn();
|
|
472
506
|
// ON = the full hands-free chain; OFF = keep checking (banner still shows) but never
|
|
@@ -1158,7 +1192,10 @@ export class TUI {
|
|
|
1158
1192
|
}
|
|
1159
1193
|
|
|
1160
1194
|
// Completed log
|
|
1161
|
-
|
|
1195
|
+
// 2 = separator + footer; confirm adds its detail line; updates adds its detail block.
|
|
1196
|
+
const footerH = this.mode === 'confirm' ? 3
|
|
1197
|
+
: this.mode === 'updates' ? 2 + this._renderUpdatesDetail().length
|
|
1198
|
+
: 2;
|
|
1162
1199
|
const space = Math.max(0, H - lines.length - footerH);
|
|
1163
1200
|
for (let i = 0; i < space && i < this.log.length; i++) {
|
|
1164
1201
|
lines.push(` ${gray(this.log[i].t)} ${this.log[i].msg}`);
|
|
@@ -1170,6 +1207,10 @@ export class TUI {
|
|
|
1170
1207
|
// ── Footer
|
|
1171
1208
|
lines.push(' ' + dim('─'.repeat(W - 2)));
|
|
1172
1209
|
if (this.mode === 'confirm') lines.push(` ${this.confirmDetail}`);
|
|
1210
|
+
// Updates DETAIL — without this, pressing 'u' changed only the one-line footer at the
|
|
1211
|
+
// very bottom of a busy screen, which reads as "nothing happened" (reported twice).
|
|
1212
|
+
// Every other mode draws something visible; this one must too.
|
|
1213
|
+
if (this.mode === 'updates') lines.push(...this._renderUpdatesDetail());
|
|
1173
1214
|
lines.push(this._renderFooter());
|
|
1174
1215
|
|
|
1175
1216
|
// Write buffer
|