maxpool 1.19.1 → 1.19.2
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 +31 -3
package/package.json
CHANGED
package/src/server.js
CHANGED
|
@@ -1355,8 +1355,16 @@ async function forwardRequest(
|
|
|
1355
1355
|
res.end();
|
|
1356
1356
|
}
|
|
1357
1357
|
} else {
|
|
1358
|
-
|
|
1359
|
-
|
|
1358
|
+
// MODEL ECHO: rewrite the provider's model id back to the client's before the
|
|
1359
|
+
// body reaches Claude Code. Computed BEFORE writeHead so a length change lands
|
|
1360
|
+
// in the SAME header block — setting content-length after writeHead is a no-op
|
|
1361
|
+
// and would ship a body/length mismatch (the client then hangs or truncates).
|
|
1362
|
+
const outBuf = normalizeModelEcho(buf, requestInfo.model);
|
|
1363
|
+
const outHeaders = outBuf === buf
|
|
1364
|
+
? responseHeaders
|
|
1365
|
+
: { ...responseHeaders, 'content-length': String(outBuf.length) };
|
|
1366
|
+
if (!res.headersSent) res.writeHead(upstreamRes.status, outHeaders);
|
|
1367
|
+
res.end(outBuf);
|
|
1360
1368
|
}
|
|
1361
1369
|
}
|
|
1362
1370
|
} catch (err) {
|
|
@@ -1657,7 +1665,7 @@ function isContextLengthError(errorBody) {
|
|
|
1657
1665
|
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);
|
|
1658
1666
|
}
|
|
1659
1667
|
|
|
1660
|
-
export const __serverTest = { reanchorOrphanedSystemMessages, unavailableMessage, computeQueueWindowMs, isRetriableUpstreamStatus, classifyEffortRejection, repairEffort, isCapacitySignalStatus, isStrippableThinkingBlock, stripForeignThinkingBlocks, parseRejectedBlockPath, stripRejectedBlockClass, peekRejectedBlockType, describeRejectedBlock, headerValue, getMaxpoolProfile, ensureQueueHeartbeat, clearQueueHeartbeat, commitStreamGraceHeartbeat, describeRequest, classifyRateLimit, detectTranscriptOrigin, isAnthropicIncompatBody, isContextLengthError, streamResponse, startIdleRequestReaper };
|
|
1668
|
+
export const __serverTest = { reanchorOrphanedSystemMessages, unavailableMessage, computeQueueWindowMs, isRetriableUpstreamStatus, classifyEffortRejection, repairEffort, isCapacitySignalStatus, isStrippableThinkingBlock, stripForeignThinkingBlocks, parseRejectedBlockPath, stripRejectedBlockClass, peekRejectedBlockType, describeRejectedBlock, headerValue, getMaxpoolProfile, ensureQueueHeartbeat, clearQueueHeartbeat, commitStreamGraceHeartbeat, describeRequest, classifyRateLimit, detectTranscriptOrigin, isAnthropicIncompatBody, isContextLengthError, streamResponse, startIdleRequestReaper, normalizeModelEcho };
|
|
1661
1669
|
|
|
1662
1670
|
async function readErrorBody(upstreamRes, limitBytes = 64 * 1024) {
|
|
1663
1671
|
if (!upstreamRes.body) return '';
|
|
@@ -2857,6 +2865,26 @@ function startIdleRequestReaper(res, reqId, idleMs, { now = Date.now, setInterva
|
|
|
2857
2865
|
}
|
|
2858
2866
|
|
|
2859
2867
|
|
|
2868
|
+
/** Rewrite a non-streaming JSON body's `model` back to the CLIENT'S requested model.
|
|
2869
|
+
* Twin of the SSE model-echo normalization in streamResponse: provider upstreams
|
|
2870
|
+
* (z.ai/GLM, Kimi) echo their own id, Claude Code persists it, and a resumed session
|
|
2871
|
+
* then prints "Session model glm-5.3 could not be restored". The streaming half
|
|
2872
|
+
* shipped in v1.19.1; this covers the buffered path, which is where the remaining
|
|
2873
|
+
* 5,719 contaminated turns came from (measured 2026-09-02). No-op when the ids
|
|
2874
|
+
* already match, when the body is not JSON, or when no client model is known. */
|
|
2875
|
+
function normalizeModelEcho(buf, clientModel) {
|
|
2876
|
+
if (!clientModel || !buf?.length) return buf;
|
|
2877
|
+
try {
|
|
2878
|
+
const json = JSON.parse(buf.toString('utf8'));
|
|
2879
|
+
if (!json || typeof json !== 'object' || typeof json.model !== 'string') return buf;
|
|
2880
|
+
if (json.model === clientModel) return buf;
|
|
2881
|
+
json.model = clientModel;
|
|
2882
|
+
return Buffer.from(JSON.stringify(json), 'utf8');
|
|
2883
|
+
} catch {
|
|
2884
|
+
return buf; // non-JSON (or truncated) body — forward untouched
|
|
2885
|
+
}
|
|
2886
|
+
}
|
|
2887
|
+
|
|
2860
2888
|
function concatUint8(chunks) {
|
|
2861
2889
|
let n = 0;
|
|
2862
2890
|
for (const c of chunks) n += c.length;
|