maxpool 1.5.29 → 1.5.30
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 +7 -0
- package/src/server.js +18 -0
package/package.json
CHANGED
package/src/account-manager.js
CHANGED
|
@@ -1609,6 +1609,13 @@ export class AccountManager {
|
|
|
1609
1609
|
_isRequestCompatible(account, profile, requestInfo = {}) {
|
|
1610
1610
|
if (!this._matchesProfile(account, profile)) return false;
|
|
1611
1611
|
|
|
1612
|
+
// Kimi (Moonshot) 400s on images Anthropic/GLM accept ("failed to decode
|
|
1613
|
+
// image") — and a provider 400 is TERMINAL (not retried to another account), so
|
|
1614
|
+
// an image request that fell back to Kimi FAILS the whole request. Keep image
|
|
1615
|
+
// requests off Kimi; they still route to GLM (handles images) + OAuth. If those
|
|
1616
|
+
// are all unavailable the request HOLDS/queues (recoverable) rather than 400ing.
|
|
1617
|
+
if (requestInfo.hasImage && account.provider === 'kimi') return false;
|
|
1618
|
+
|
|
1612
1619
|
const { incompatible, homeProvider } = this._effectiveIncompatible(requestInfo);
|
|
1613
1620
|
const policy = this._crossProviderFallbackPolicy();
|
|
1614
1621
|
|
package/src/server.js
CHANGED
|
@@ -1593,6 +1593,9 @@ function describeRequest(req, body) {
|
|
|
1593
1593
|
const origin = detectTranscriptOrigin(json);
|
|
1594
1594
|
if (origin.anthropicIncompatible) info.anthropicIncompatible = true;
|
|
1595
1595
|
if (origin.homeProvider) info.homeProvider = origin.homeProvider;
|
|
1596
|
+
// Image content (incl. tool_result-nested screenshots) keeps a request off Kimi
|
|
1597
|
+
// (Moonshot 400s on some images GLM/Anthropic accept, and a 400 is terminal).
|
|
1598
|
+
if (containsImageBlock(json.messages)) info.hasImage = true;
|
|
1596
1599
|
} catch {
|
|
1597
1600
|
// Non-JSON requests are rare; body size still gives a useful load signal.
|
|
1598
1601
|
}
|
|
@@ -1679,6 +1682,21 @@ function containsThinkingBlock(value) {
|
|
|
1679
1682
|
return false;
|
|
1680
1683
|
}
|
|
1681
1684
|
|
|
1685
|
+
// True if any message carries an `{type:'image'}` content block at ANY nesting
|
|
1686
|
+
// depth — including images nested inside a `tool_result` block (the primary
|
|
1687
|
+
// Claude Code image path: a browser/Playwright tool returning a screenshot). A
|
|
1688
|
+
// shallow 2-level scan misses those. Used to keep image requests off Kimi, whose
|
|
1689
|
+
// decoder 400s on images Anthropic/GLM accept.
|
|
1690
|
+
function containsImageBlock(value) {
|
|
1691
|
+
if (!value) return false;
|
|
1692
|
+
if (Array.isArray(value)) return value.some(containsImageBlock);
|
|
1693
|
+
if (typeof value !== 'object') return false;
|
|
1694
|
+
if (value.type === 'image') return true;
|
|
1695
|
+
if (value.content && containsImageBlock(value.content)) return true;
|
|
1696
|
+
if (value.messages && containsImageBlock(value.messages)) return true;
|
|
1697
|
+
return false;
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1682
1700
|
function getMaxpoolProfile(headers) {
|
|
1683
1701
|
// headerValue() handles the x-teamclaude-* legacy fallback.
|
|
1684
1702
|
const profile = String(headerValue(headers, 'x-maxpool-profile') || 'claude').trim().toLowerCase();
|