@kenkaiiii/gg-core 5.89.0 → 5.91.0
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/dist/{chunk-5ZYOOESD.js → chunk-M53JVW2V.js} +168 -4
- package/dist/chunk-M53JVW2V.js.map +1 -0
- package/dist/index.cjs +250 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +74 -20
- package/dist/index.d.ts +74 -20
- package/dist/index.js +87 -15
- package/dist/index.js.map +1 -1
- package/dist/model-registry.cjs +20 -1
- package/dist/model-registry.cjs.map +1 -1
- package/dist/model-registry.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-5ZYOOESD.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -40,6 +40,8 @@ __export(index_exports, {
|
|
|
40
40
|
HIDDEN_PROVIDERS: () => HIDDEN_PROVIDERS,
|
|
41
41
|
LOCAL_API_KEY_PLACEHOLDER: () => LOCAL_API_KEY_PLACEHOLDER,
|
|
42
42
|
LOCAL_AUTH_KEY_PREFIX: () => LOCAL_AUTH_KEY_PREFIX,
|
|
43
|
+
MINIMAX_CN_BASE_URL: () => MINIMAX_CN_BASE_URL,
|
|
44
|
+
MINIMAX_GLOBAL_BASE_URL: () => MINIMAX_GLOBAL_BASE_URL,
|
|
43
45
|
MODELS: () => MODELS,
|
|
44
46
|
MOONSHOT_OAUTH_KEY: () => MOONSHOT_OAUTH_KEY,
|
|
45
47
|
NotLoggedInError: () => NotLoggedInError,
|
|
@@ -48,6 +50,7 @@ __export(index_exports, {
|
|
|
48
50
|
TelegramBot: () => TelegramBot,
|
|
49
51
|
XAI_OAUTH_KEY: () => XAI_OAUTH_KEY,
|
|
50
52
|
XIAOMI_CREDITS_KEY: () => XIAOMI_CREDITS_KEY,
|
|
53
|
+
XIAOMI_TOKEN_PLAN_BASE_URLS: () => XIAOMI_TOKEN_PLAN_BASE_URLS,
|
|
51
54
|
authPriorityNote: () => authPriorityNote,
|
|
52
55
|
clampThinkingForPlanMode: () => clampThinkingForPlanMode,
|
|
53
56
|
clearLocalDiscoveryCache: () => clearLocalDiscoveryCache,
|
|
@@ -56,6 +59,8 @@ __export(index_exports, {
|
|
|
56
59
|
createAutoUpdater: () => createAutoUpdater,
|
|
57
60
|
decodeOggOpus: () => decodeOggOpus,
|
|
58
61
|
describeAuthMethods: () => describeAuthMethods,
|
|
62
|
+
detectMiniMaxBaseUrl: () => detectMiniMaxBaseUrl,
|
|
63
|
+
detectXiaomiTokenPlanBaseUrl: () => detectXiaomiTokenPlanBaseUrl,
|
|
59
64
|
discoverLocalModels: () => discoverLocalModels,
|
|
60
65
|
downmixToMono: () => downmixToMono,
|
|
61
66
|
dualAuthProvider: () => dualAuthProvider,
|
|
@@ -99,6 +104,7 @@ __export(index_exports, {
|
|
|
99
104
|
kimiCodeBaseUrl: () => kimiCodeBaseUrl,
|
|
100
105
|
kimiCodingHeaders: () => kimiCodingHeaders,
|
|
101
106
|
localAuthStorageKey: () => localAuthStorageKey,
|
|
107
|
+
localModelShortName: () => localModelShortName,
|
|
102
108
|
log: () => log,
|
|
103
109
|
loginAnthropic: () => loginAnthropic,
|
|
104
110
|
loginGemini: () => loginGemini,
|
|
@@ -106,6 +112,7 @@ __export(index_exports, {
|
|
|
106
112
|
loginOpenAI: () => loginOpenAI,
|
|
107
113
|
loginXai: () => loginXai,
|
|
108
114
|
oauthStorageKey: () => oauthStorageKey,
|
|
115
|
+
ollamaServedContext: () => ollamaServedContext,
|
|
109
116
|
openLog: () => openLog,
|
|
110
117
|
parseLocalModelId: () => parseLocalModelId,
|
|
111
118
|
pendingClaudeCodeVersionRefresh: () => import_gg_ai.pendingClaudeCodeVersionRefresh,
|
|
@@ -1524,6 +1531,91 @@ function isHiddenProvider(provider) {
|
|
|
1524
1531
|
return HIDDEN_PROVIDERS.includes(provider);
|
|
1525
1532
|
}
|
|
1526
1533
|
|
|
1534
|
+
// src/auth-storage.ts
|
|
1535
|
+
var import_gg_ai3 = require("@kenkaiiii/gg-ai");
|
|
1536
|
+
|
|
1537
|
+
// src/minimax-region.ts
|
|
1538
|
+
var MINIMAX_GLOBAL_BASE_URL = "https://api.minimax.io/anthropic";
|
|
1539
|
+
var MINIMAX_CN_BASE_URL = "https://api.minimax.cn/anthropic";
|
|
1540
|
+
var REGION_HOSTS = [
|
|
1541
|
+
{ host: "https://api.minimax.io", baseUrl: MINIMAX_GLOBAL_BASE_URL },
|
|
1542
|
+
{ host: "https://api.minimax.cn", baseUrl: MINIMAX_CN_BASE_URL }
|
|
1543
|
+
];
|
|
1544
|
+
var KEY_KNOWN_CODES = /* @__PURE__ */ new Set([0, 2062]);
|
|
1545
|
+
var KEY_REJECTED_CODES = /* @__PURE__ */ new Set([1004, 2049]);
|
|
1546
|
+
async function probeRegion(host, apiKey, fetchImpl, timeoutMs) {
|
|
1547
|
+
const url = apiKey.startsWith("sk-api-") ? `${host}/account/query_balance` : `${host}/v1/token_plan/remains`;
|
|
1548
|
+
let sawRejection = false;
|
|
1549
|
+
const authHeaders2 = [
|
|
1550
|
+
{ Authorization: `Bearer ${apiKey}` },
|
|
1551
|
+
{ "x-api-key": apiKey }
|
|
1552
|
+
];
|
|
1553
|
+
for (const auth of authHeaders2) {
|
|
1554
|
+
let res;
|
|
1555
|
+
try {
|
|
1556
|
+
res = await fetchImpl(url, {
|
|
1557
|
+
headers: { ...auth, "Content-Type": "application/json" },
|
|
1558
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
1559
|
+
});
|
|
1560
|
+
} catch {
|
|
1561
|
+
return "inconclusive";
|
|
1562
|
+
}
|
|
1563
|
+
if (res.status === 401 || res.status === 403) {
|
|
1564
|
+
sawRejection = true;
|
|
1565
|
+
continue;
|
|
1566
|
+
}
|
|
1567
|
+
if (!res.ok) return "inconclusive";
|
|
1568
|
+
let code;
|
|
1569
|
+
try {
|
|
1570
|
+
code = (await res.json()).base_resp?.status_code;
|
|
1571
|
+
} catch {
|
|
1572
|
+
return "inconclusive";
|
|
1573
|
+
}
|
|
1574
|
+
if (typeof code === "number" && KEY_KNOWN_CODES.has(code)) return "authorized";
|
|
1575
|
+
if (typeof code === "number" && KEY_REJECTED_CODES.has(code)) {
|
|
1576
|
+
sawRejection = true;
|
|
1577
|
+
continue;
|
|
1578
|
+
}
|
|
1579
|
+
return "inconclusive";
|
|
1580
|
+
}
|
|
1581
|
+
return sawRejection ? "unauthorized" : "inconclusive";
|
|
1582
|
+
}
|
|
1583
|
+
async function detectMiniMaxBaseUrl(apiKey, options = {}) {
|
|
1584
|
+
const fetchImpl = options.fetch ?? fetch;
|
|
1585
|
+
const timeoutMs = options.timeoutMs ?? 5e3;
|
|
1586
|
+
const results = await Promise.all(
|
|
1587
|
+
REGION_HOSTS.map((r) => probeRegion(r.host, apiKey, fetchImpl, timeoutMs))
|
|
1588
|
+
);
|
|
1589
|
+
const index = results.indexOf("authorized");
|
|
1590
|
+
return index === -1 ? void 0 : REGION_HOSTS[index].baseUrl;
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1593
|
+
// src/xiaomi-region.ts
|
|
1594
|
+
var XIAOMI_TOKEN_PLAN_BASE_URLS = [
|
|
1595
|
+
"https://token-plan-sgp.xiaomimimo.com/v1",
|
|
1596
|
+
"https://token-plan-ams.xiaomimimo.com/v1",
|
|
1597
|
+
"https://token-plan-cn.xiaomimimo.com/v1"
|
|
1598
|
+
];
|
|
1599
|
+
async function detectXiaomiTokenPlanBaseUrl(apiKey, options = {}) {
|
|
1600
|
+
const fetchImpl = options.fetch ?? fetch;
|
|
1601
|
+
const timeoutMs = options.timeoutMs ?? 5e3;
|
|
1602
|
+
const accepted = await Promise.all(
|
|
1603
|
+
XIAOMI_TOKEN_PLAN_BASE_URLS.map(async (baseUrl) => {
|
|
1604
|
+
try {
|
|
1605
|
+
const res = await fetchImpl(`${baseUrl}/models`, {
|
|
1606
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
1607
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
1608
|
+
});
|
|
1609
|
+
return res.ok;
|
|
1610
|
+
} catch {
|
|
1611
|
+
return false;
|
|
1612
|
+
}
|
|
1613
|
+
})
|
|
1614
|
+
);
|
|
1615
|
+
const index = accepted.indexOf(true);
|
|
1616
|
+
return index === -1 ? void 0 : XIAOMI_TOKEN_PLAN_BASE_URLS[index];
|
|
1617
|
+
}
|
|
1618
|
+
|
|
1527
1619
|
// src/auth-storage.ts
|
|
1528
1620
|
var MOONSHOT_OAUTH_KEY = "moonshot-oauth";
|
|
1529
1621
|
var XAI_OAUTH_KEY = "xai-oauth";
|
|
@@ -1574,6 +1666,15 @@ function activeBaseUrlEntry(data, provider) {
|
|
|
1574
1666
|
}
|
|
1575
1667
|
return data[provider];
|
|
1576
1668
|
}
|
|
1669
|
+
var MINIMAX_REGION_RETRY_MS = 5 * 60 * 1e3;
|
|
1670
|
+
var miniMaxRegionProbes = /* @__PURE__ */ new Map();
|
|
1671
|
+
function cachedMiniMaxRegion(apiKey) {
|
|
1672
|
+
const cached = miniMaxRegionProbes.get(apiKey);
|
|
1673
|
+
if (cached && Date.now() - cached.at < MINIMAX_REGION_RETRY_MS) return cached.result;
|
|
1674
|
+
const result = detectMiniMaxBaseUrl(apiKey).catch(() => void 0);
|
|
1675
|
+
miniMaxRegionProbes.set(apiKey, { at: Date.now(), result });
|
|
1676
|
+
return result;
|
|
1677
|
+
}
|
|
1577
1678
|
function readStoredBaseUrlSync(authFile, provider) {
|
|
1578
1679
|
try {
|
|
1579
1680
|
const data = JSON.parse((0, import_node_fs3.readFileSync)(authFile, "utf-8"));
|
|
@@ -1620,8 +1721,12 @@ var AuthStorage = class {
|
|
|
1620
1721
|
snapshotIno = 0;
|
|
1621
1722
|
/** Per-provider lock to serialize concurrent refresh calls. */
|
|
1622
1723
|
refreshLocks = /* @__PURE__ */ new Map();
|
|
1623
|
-
|
|
1724
|
+
detectMiniMaxRegion;
|
|
1725
|
+
detectXiaomiCluster;
|
|
1726
|
+
constructor(filePath, options) {
|
|
1624
1727
|
this.filePath = filePath ?? getAppPaths().authFile;
|
|
1728
|
+
this.detectMiniMaxRegion = options?.detectMiniMaxBaseUrl ?? cachedMiniMaxRegion;
|
|
1729
|
+
this.detectXiaomiCluster = options?.detectXiaomiTokenPlanBaseUrl ?? detectXiaomiTokenPlanBaseUrl;
|
|
1625
1730
|
}
|
|
1626
1731
|
/** Path to the on-disk auth file. Useful for status output. */
|
|
1627
1732
|
get path() {
|
|
@@ -1683,7 +1788,7 @@ var AuthStorage = class {
|
|
|
1683
1788
|
*/
|
|
1684
1789
|
async setLocalEndpoint(endpointId, baseUrl, apiKey) {
|
|
1685
1790
|
await this.setCredentials(`${LOCAL_AUTH_KEY_PREFIX}${endpointId}`, {
|
|
1686
|
-
accessToken: apiKey && apiKey.length > 0 ? apiKey :
|
|
1791
|
+
accessToken: apiKey && apiKey.length > 0 ? apiKey : import_gg_ai3.LOCAL_NO_API_KEY,
|
|
1687
1792
|
refreshToken: "",
|
|
1688
1793
|
expiresAt: Date.now() + LOCAL_CREDENTIAL_LIFETIME_MS,
|
|
1689
1794
|
baseUrl
|
|
@@ -1820,11 +1925,54 @@ var AuthStorage = class {
|
|
|
1820
1925
|
await this.ensureFresh();
|
|
1821
1926
|
return this.data[provider];
|
|
1822
1927
|
}
|
|
1928
|
+
/**
|
|
1929
|
+
* A MiniMax key saved without an endpoint (every key, until its first use)
|
|
1930
|
+
* gets the endpoint of the region that issued it, saved so the check runs
|
|
1931
|
+
* once. Without this a Mainland China key went to the Global API, got a 401,
|
|
1932
|
+
* and was deleted as invalid.
|
|
1933
|
+
*/
|
|
1934
|
+
async withMiniMaxRegion(creds) {
|
|
1935
|
+
const baseUrl = await this.detectMiniMaxRegion(creds.accessToken);
|
|
1936
|
+
if (!baseUrl) return creds;
|
|
1937
|
+
log("INFO", "auth", `MiniMax key belongs to ${baseUrl} \u2014 saved for future requests`);
|
|
1938
|
+
await this.mutateLatest((latest) => {
|
|
1939
|
+
const current = latest["minimax"];
|
|
1940
|
+
if (current?.accessToken === creds.accessToken && !current.baseUrl) {
|
|
1941
|
+
current.baseUrl = baseUrl;
|
|
1942
|
+
}
|
|
1943
|
+
});
|
|
1944
|
+
return { ...creds, baseUrl };
|
|
1945
|
+
}
|
|
1823
1946
|
async setCredentials(provider, creds) {
|
|
1824
1947
|
await this.mutateLatest((latest) => {
|
|
1825
1948
|
latest[provider] = creds;
|
|
1826
1949
|
});
|
|
1827
1950
|
}
|
|
1951
|
+
/**
|
|
1952
|
+
* After a 401, move a regional key to the cluster that issued it instead of
|
|
1953
|
+
* treating it as invalid. Only the Xiaomi Token Plan is regional: every key
|
|
1954
|
+
* used to go to Singapore, so Europe and China keys were rejected and deleted.
|
|
1955
|
+
* Returns the new base URL, or undefined when no other cluster accepts the key.
|
|
1956
|
+
*/
|
|
1957
|
+
async relocateRegionalApiKey(storageKeys) {
|
|
1958
|
+
const key = await this.pickStorageKey(storageKeys);
|
|
1959
|
+
const creds = key === "xiaomi" ? this.data[key] : void 0;
|
|
1960
|
+
if (!creds) return void 0;
|
|
1961
|
+
const baseUrl = await this.detectXiaomiCluster(creds.accessToken);
|
|
1962
|
+
if (!baseUrl || baseUrl === creds.baseUrl) return void 0;
|
|
1963
|
+
await this.mutateLatest((latest) => {
|
|
1964
|
+
const current = latest["xiaomi"];
|
|
1965
|
+
if (current?.accessToken === creds.accessToken) current.baseUrl = baseUrl;
|
|
1966
|
+
});
|
|
1967
|
+
log("INFO", "auth", `Xiaomi Token Plan key belongs to ${baseUrl} \u2014 saved for future requests`);
|
|
1968
|
+
return baseUrl;
|
|
1969
|
+
}
|
|
1970
|
+
// Keeps local-endpoint keys: they're the user's own config, and a 401 there is often a busy gateway.
|
|
1971
|
+
async clearRejectedApiKey(storageKey) {
|
|
1972
|
+
if (storageKey.startsWith(LOCAL_AUTH_KEY_PREFIX)) return false;
|
|
1973
|
+
await this.clearCredentials(storageKey);
|
|
1974
|
+
return true;
|
|
1975
|
+
}
|
|
1828
1976
|
async clearCredentials(provider) {
|
|
1829
1977
|
await this.mutateLatest((latest) => {
|
|
1830
1978
|
delete latest[provider];
|
|
@@ -1938,6 +2086,7 @@ var AuthStorage = class {
|
|
|
1938
2086
|
throw new NotLoggedInError(provider);
|
|
1939
2087
|
}
|
|
1940
2088
|
if (STATIC_API_KEY_PROVIDERS.has(provider)) {
|
|
2089
|
+
if (provider === "minimax" && !creds.baseUrl) return await this.withMiniMaxRegion(creds);
|
|
1941
2090
|
return creds;
|
|
1942
2091
|
}
|
|
1943
2092
|
if (!opts?.forceRefresh && Date.now() < creds.expiresAt - refreshThresholdMs(creds)) {
|
|
@@ -2588,6 +2737,23 @@ var MODELS = [
|
|
|
2588
2737
|
maxThinkingLevel: "max"
|
|
2589
2738
|
},
|
|
2590
2739
|
// ── MiniMax ────────────────────────────────────────────
|
|
2740
|
+
{
|
|
2741
|
+
// The only text model M Plan / Token Plan keys cover; MiniMax-M3 on those
|
|
2742
|
+
// keys fails with "insufficient balance (1008)". Pay-as-you-go serves both.
|
|
2743
|
+
// Always thinks (`thinking: disabled` 400s; omitted = on) with a real
|
|
2744
|
+
// low→max effort ladder on output_config.effort, API default max.
|
|
2745
|
+
id: "MiniMax-M3.1-Flash",
|
|
2746
|
+
name: "MiniMax M3.1 Flash",
|
|
2747
|
+
provider: "minimax",
|
|
2748
|
+
contextWindow: 1e6,
|
|
2749
|
+
maxOutputTokens: 131072,
|
|
2750
|
+
supportsThinking: true,
|
|
2751
|
+
supportsImages: true,
|
|
2752
|
+
supportsVideo: true,
|
|
2753
|
+
maxVideoBytes: 50 * 1024 * 1024,
|
|
2754
|
+
costTier: "low",
|
|
2755
|
+
maxThinkingLevel: "max"
|
|
2756
|
+
},
|
|
2591
2757
|
{
|
|
2592
2758
|
id: "MiniMax-M3",
|
|
2593
2759
|
name: "MiniMax M3",
|
|
@@ -2838,7 +3004,7 @@ var DEFAULT_MODEL_IDS = {
|
|
|
2838
3004
|
gemini: "gemini-3.1-flash-lite",
|
|
2839
3005
|
glm: "glm-5.3",
|
|
2840
3006
|
moonshot: "kimi-k3",
|
|
2841
|
-
minimax: "MiniMax-M3",
|
|
3007
|
+
minimax: "MiniMax-M3.1-Flash",
|
|
2842
3008
|
deepseek: "deepseek-v4-pro",
|
|
2843
3009
|
huggingface: "moonshotai/Kimi-K2.7-Code",
|
|
2844
3010
|
openrouter: "qwen/qwen3.8-max",
|
|
@@ -2932,6 +3098,13 @@ var ANTHROPIC_ADAPTIVE_THINKING_LEVELS = [
|
|
|
2932
3098
|
];
|
|
2933
3099
|
var MOONSHOT_K3_THINKING_LEVELS = ["low", "high", "max"];
|
|
2934
3100
|
var GLM_THINKING_LEVELS = ["low", "medium", "high", "xhigh", "max"];
|
|
3101
|
+
var MINIMAX_EFFORT_THINKING_LEVELS = [
|
|
3102
|
+
"low",
|
|
3103
|
+
"medium",
|
|
3104
|
+
"high",
|
|
3105
|
+
"xhigh",
|
|
3106
|
+
"max"
|
|
3107
|
+
];
|
|
2935
3108
|
var LOCAL_THINKING_LEVELS = ["low", "medium", "high", "max"];
|
|
2936
3109
|
function isOpenAIGptModel(provider, model) {
|
|
2937
3110
|
return provider === "openai" && model.startsWith("gpt-");
|
|
@@ -2948,6 +3121,9 @@ function isMoonshotK3Model(provider, model) {
|
|
|
2948
3121
|
function isGlmModel(provider) {
|
|
2949
3122
|
return provider === "glm";
|
|
2950
3123
|
}
|
|
3124
|
+
function isMiniMaxEffortModel(provider, model) {
|
|
3125
|
+
return provider === "minimax" && model.startsWith("MiniMax-M3.1");
|
|
3126
|
+
}
|
|
2951
3127
|
function isAnthropicXhighModel(provider, model) {
|
|
2952
3128
|
return provider === "anthropic" && /opus-5|opus-4-8|opus-4-7|sonnet-5[-.]5|haiku-5[-.]5/.test(model);
|
|
2953
3129
|
}
|
|
@@ -2980,6 +3156,7 @@ function getSupportedThinkingLevels(provider, model) {
|
|
|
2980
3156
|
}
|
|
2981
3157
|
if (isMoonshotK3Model(provider, model)) return MOONSHOT_K3_THINKING_LEVELS;
|
|
2982
3158
|
if (provider === "deepseek") return DEEPSEEK_THINKING_LEVELS;
|
|
3159
|
+
if (isMiniMaxEffortModel(provider, model)) return MINIMAX_EFFORT_THINKING_LEVELS;
|
|
2983
3160
|
if (isGlmModel(provider)) {
|
|
2984
3161
|
const maxIndex2 = GLM_THINKING_LEVELS.indexOf(maxLevel);
|
|
2985
3162
|
if (maxIndex2 === -1) return GLM_THINKING_LEVELS;
|
|
@@ -3000,7 +3177,7 @@ function isThinkingLevelSupported(provider, model, level) {
|
|
|
3000
3177
|
}
|
|
3001
3178
|
function getNextThinkingLevel(provider, model, current) {
|
|
3002
3179
|
const supportedLevels = getSupportedThinkingLevels(provider, model);
|
|
3003
|
-
const shouldCycleLevels = isOpenAIGptModel(provider, model) || isAnthropicAdaptiveModel(provider, model) || isSakanaModel(provider) || isXaiModel(provider) || isMoonshotK3Model(provider, model) || isGlmModel(provider) || provider === "deepseek" || // Local servers take a real effort level, not just on/off: Ollama accepts
|
|
3180
|
+
const shouldCycleLevels = isOpenAIGptModel(provider, model) || isAnthropicAdaptiveModel(provider, model) || isSakanaModel(provider) || isXaiModel(provider) || isMoonshotK3Model(provider, model) || isGlmModel(provider) || isMiniMaxEffortModel(provider, model) || provider === "deepseek" || // Local servers take a real effort level, not just on/off: Ollama accepts
|
|
3004
3181
|
// low/medium/high on `reasoning_effort` (verified against 0.32) and the
|
|
3005
3182
|
// other OpenAI-compatible servers use the same three. A model that can't
|
|
3006
3183
|
// reason at all already has no supported levels, so it never gets here.
|
|
@@ -3028,11 +3205,12 @@ function clampThinkingForPlanMode(level) {
|
|
|
3028
3205
|
}
|
|
3029
3206
|
|
|
3030
3207
|
// src/local-models.ts
|
|
3208
|
+
var import_gg_ai4 = require("@kenkaiiii/gg-ai");
|
|
3031
3209
|
var DEFAULT_LOCAL_ENDPOINTS = [
|
|
3032
3210
|
{ id: "ollama", label: "Ollama", baseUrl: "http://127.0.0.1:11434/v1", kind: "ollama" }
|
|
3033
3211
|
];
|
|
3034
3212
|
var FALLBACK_CONTEXT_WINDOW = 4096;
|
|
3035
|
-
var LOCAL_API_KEY_PLACEHOLDER =
|
|
3213
|
+
var LOCAL_API_KEY_PLACEHOLDER = import_gg_ai4.LOCAL_NO_API_KEY;
|
|
3036
3214
|
var DEFAULT_PROBE_TIMEOUT_MS = 1200;
|
|
3037
3215
|
var ENRICH_CONCURRENCY = 6;
|
|
3038
3216
|
var CACHE_TTL_MS = 3e4;
|
|
@@ -3048,6 +3226,9 @@ function parseLocalModelId(id) {
|
|
|
3048
3226
|
if (slash <= 0 || slash === rest.length - 1) return void 0;
|
|
3049
3227
|
return { endpointId: rest.slice(0, slash), rawId: rest.slice(slash + 1) };
|
|
3050
3228
|
}
|
|
3229
|
+
function localModelShortName(rawId) {
|
|
3230
|
+
return rawId.slice(rawId.lastIndexOf("/") + 1) || rawId;
|
|
3231
|
+
}
|
|
3051
3232
|
function isLocalModelId(id) {
|
|
3052
3233
|
return parseLocalModelId(id) !== void 0;
|
|
3053
3234
|
}
|
|
@@ -3058,8 +3239,9 @@ function endpointRoot(baseUrl) {
|
|
|
3058
3239
|
return baseUrl.replace(/\/+$/, "").replace(/\/v1$/, "");
|
|
3059
3240
|
}
|
|
3060
3241
|
function authHeaders(endpoint) {
|
|
3242
|
+
const key = (0, import_gg_ai4.localBearerKey)(endpoint.apiKey);
|
|
3061
3243
|
return {
|
|
3062
|
-
Authorization: `Bearer ${
|
|
3244
|
+
...key ? { Authorization: `Bearer ${key}` } : {},
|
|
3063
3245
|
Accept: "application/json"
|
|
3064
3246
|
};
|
|
3065
3247
|
}
|
|
@@ -3121,10 +3303,22 @@ async function enrich(endpoint, entries, options) {
|
|
|
3121
3303
|
if (endpoint.kind === "lmstudio") return enrichLmStudio(endpoint, entries, options);
|
|
3122
3304
|
if (endpoint.kind === "ollama") return enrichOllama(endpoint, entries, options);
|
|
3123
3305
|
if (endpoint.kind === "llamacpp") return enrichLlamaCpp(endpoint, entries, options);
|
|
3306
|
+
if (endpoint.kind === "custom") return enrichCustom(endpoint, entries, options);
|
|
3124
3307
|
return entries.map((entry) => genericModel(endpoint, entry));
|
|
3125
3308
|
}
|
|
3309
|
+
async function enrichCustom(endpoint, entries, options) {
|
|
3310
|
+
const generic = entries.map((entry) => genericModel(endpoint, entry));
|
|
3311
|
+
if (generic.every((model) => model.contextWindowKnown)) return generic;
|
|
3312
|
+
const root = endpointRoot(endpoint.baseUrl);
|
|
3313
|
+
const props = await fetchJson(`${root}/props`, endpoint, options);
|
|
3314
|
+
const nCtx = contextLength(props?.default_generation_settings?.n_ctx);
|
|
3315
|
+
if (nCtx !== void 0) return llamaCppModels(endpoint, entries, nCtx);
|
|
3316
|
+
const lmStudio = await fetchJson(`${root}/api/v1/models`, endpoint, options);
|
|
3317
|
+
if (Array.isArray(lmStudio?.models)) return enrichLmStudio(endpoint, entries, options, lmStudio);
|
|
3318
|
+
return generic;
|
|
3319
|
+
}
|
|
3126
3320
|
function genericModel(endpoint, entry) {
|
|
3127
|
-
const declared = contextLength(entry.max_model_len);
|
|
3321
|
+
const declared = contextLength(entry.max_model_len) ?? contextLength(entry.context_length);
|
|
3128
3322
|
return {
|
|
3129
3323
|
rawId: entry.id,
|
|
3130
3324
|
endpointId: endpoint.id,
|
|
@@ -3151,9 +3345,7 @@ async function enrichOllama(endpoint, entries, options) {
|
|
|
3151
3345
|
});
|
|
3152
3346
|
const caps = Array.isArray(show?.capabilities) ? show.capabilities : [];
|
|
3153
3347
|
if (caps.includes("embedding") && !caps.includes("completion")) return void 0;
|
|
3154
|
-
const ctx =
|
|
3155
|
-
runningModels.find((model) => model?.name === entry.id || model?.model === entry.id)?.context_length
|
|
3156
|
-
);
|
|
3348
|
+
const ctx = runningContext(runningModels, entry.id) ?? modelfileNumCtx(show?.parameters);
|
|
3157
3349
|
return {
|
|
3158
3350
|
rawId: entry.id,
|
|
3159
3351
|
endpointId: endpoint.id,
|
|
@@ -3168,12 +3360,41 @@ async function enrichOllama(endpoint, entries, options) {
|
|
|
3168
3360
|
});
|
|
3169
3361
|
return enriched.filter((model) => model !== void 0);
|
|
3170
3362
|
}
|
|
3363
|
+
function runningContext(models, rawId) {
|
|
3364
|
+
return contextLength(
|
|
3365
|
+
models.find((model) => model?.name === rawId || model?.model === rawId)?.context_length
|
|
3366
|
+
);
|
|
3367
|
+
}
|
|
3368
|
+
function modelfileNumCtx(parameters) {
|
|
3369
|
+
const match = /^num_ctx\s+(\d+)\s*$/m.exec(parameters ?? "");
|
|
3370
|
+
return match ? contextLength(Number(match[1])) : void 0;
|
|
3371
|
+
}
|
|
3372
|
+
async function ollamaServedContext(endpoint, rawId, {
|
|
3373
|
+
load = false,
|
|
3374
|
+
timeoutMs = 12e4,
|
|
3375
|
+
signal
|
|
3376
|
+
} = {}) {
|
|
3377
|
+
const root = endpointRoot(endpoint.baseUrl);
|
|
3378
|
+
if (load) {
|
|
3379
|
+
await fetchJson(`${root}/api/generate`, endpoint, {
|
|
3380
|
+
timeoutMs,
|
|
3381
|
+
signal,
|
|
3382
|
+
method: "POST",
|
|
3383
|
+
body: { model: rawId }
|
|
3384
|
+
});
|
|
3385
|
+
}
|
|
3386
|
+
const running = await fetchJson(`${root}/api/ps`, endpoint, {
|
|
3387
|
+
timeoutMs: DEFAULT_PROBE_TIMEOUT_MS,
|
|
3388
|
+
signal
|
|
3389
|
+
});
|
|
3390
|
+
return runningContext(Array.isArray(running?.models) ? running.models : [], rawId);
|
|
3391
|
+
}
|
|
3171
3392
|
function contextLength(value) {
|
|
3172
3393
|
return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : void 0;
|
|
3173
3394
|
}
|
|
3174
|
-
async function enrichLmStudio(endpoint, entries, options) {
|
|
3395
|
+
async function enrichLmStudio(endpoint, entries, options, fetched) {
|
|
3175
3396
|
const root = endpointRoot(endpoint.baseUrl);
|
|
3176
|
-
const detail = await fetchJson(`${root}/api/v1/models`, endpoint, options);
|
|
3397
|
+
const detail = fetched ?? await fetchJson(`${root}/api/v1/models`, endpoint, options);
|
|
3177
3398
|
const byId = /* @__PURE__ */ new Map();
|
|
3178
3399
|
if (Array.isArray(detail?.models)) {
|
|
3179
3400
|
for (const model of detail.models) {
|
|
@@ -3231,12 +3452,17 @@ async function enrichLlamaCpp(endpoint, entries, options) {
|
|
|
3231
3452
|
endpoint,
|
|
3232
3453
|
options
|
|
3233
3454
|
);
|
|
3234
|
-
|
|
3235
|
-
|
|
3455
|
+
return llamaCppModels(
|
|
3456
|
+
endpoint,
|
|
3457
|
+
entries,
|
|
3458
|
+
contextLength(props?.default_generation_settings?.n_ctx)
|
|
3459
|
+
);
|
|
3460
|
+
}
|
|
3461
|
+
function llamaCppModels(endpoint, entries, nCtx) {
|
|
3236
3462
|
return entries.map((entry) => ({
|
|
3237
3463
|
...genericModel(endpoint, entry),
|
|
3238
|
-
contextWindow:
|
|
3239
|
-
contextWindowKnown:
|
|
3464
|
+
contextWindow: nCtx ?? FALLBACK_CONTEXT_WINDOW,
|
|
3465
|
+
contextWindowKnown: nCtx !== void 0
|
|
3240
3466
|
}));
|
|
3241
3467
|
}
|
|
3242
3468
|
async function mapLimited(items, limit, fn) {
|
|
@@ -3393,7 +3619,7 @@ var ALL_AUTH_PROVIDERS = [
|
|
|
3393
3619
|
{
|
|
3394
3620
|
value: "minimax",
|
|
3395
3621
|
label: "MiniMax",
|
|
3396
|
-
description: "MiniMax M3",
|
|
3622
|
+
description: "MiniMax M3.1 Flash, M3",
|
|
3397
3623
|
methods: ["apikey"],
|
|
3398
3624
|
apiKeyLabel: "MiniMax"
|
|
3399
3625
|
},
|
|
@@ -4226,6 +4452,8 @@ function createAutoUpdater(config) {
|
|
|
4226
4452
|
HIDDEN_PROVIDERS,
|
|
4227
4453
|
LOCAL_API_KEY_PLACEHOLDER,
|
|
4228
4454
|
LOCAL_AUTH_KEY_PREFIX,
|
|
4455
|
+
MINIMAX_CN_BASE_URL,
|
|
4456
|
+
MINIMAX_GLOBAL_BASE_URL,
|
|
4229
4457
|
MODELS,
|
|
4230
4458
|
MOONSHOT_OAUTH_KEY,
|
|
4231
4459
|
NotLoggedInError,
|
|
@@ -4234,6 +4462,7 @@ function createAutoUpdater(config) {
|
|
|
4234
4462
|
TelegramBot,
|
|
4235
4463
|
XAI_OAUTH_KEY,
|
|
4236
4464
|
XIAOMI_CREDITS_KEY,
|
|
4465
|
+
XIAOMI_TOKEN_PLAN_BASE_URLS,
|
|
4237
4466
|
authPriorityNote,
|
|
4238
4467
|
clampThinkingForPlanMode,
|
|
4239
4468
|
clearLocalDiscoveryCache,
|
|
@@ -4242,6 +4471,8 @@ function createAutoUpdater(config) {
|
|
|
4242
4471
|
createAutoUpdater,
|
|
4243
4472
|
decodeOggOpus,
|
|
4244
4473
|
describeAuthMethods,
|
|
4474
|
+
detectMiniMaxBaseUrl,
|
|
4475
|
+
detectXiaomiTokenPlanBaseUrl,
|
|
4245
4476
|
discoverLocalModels,
|
|
4246
4477
|
downmixToMono,
|
|
4247
4478
|
dualAuthProvider,
|
|
@@ -4285,6 +4516,7 @@ function createAutoUpdater(config) {
|
|
|
4285
4516
|
kimiCodeBaseUrl,
|
|
4286
4517
|
kimiCodingHeaders,
|
|
4287
4518
|
localAuthStorageKey,
|
|
4519
|
+
localModelShortName,
|
|
4288
4520
|
log,
|
|
4289
4521
|
loginAnthropic,
|
|
4290
4522
|
loginGemini,
|
|
@@ -4292,6 +4524,7 @@ function createAutoUpdater(config) {
|
|
|
4292
4524
|
loginOpenAI,
|
|
4293
4525
|
loginXai,
|
|
4294
4526
|
oauthStorageKey,
|
|
4527
|
+
ollamaServedContext,
|
|
4295
4528
|
openLog,
|
|
4296
4529
|
parseLocalModelId,
|
|
4297
4530
|
pendingClaudeCodeVersionRefresh,
|