@kenkaiiii/gg-core 5.90.0 → 5.91.1

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/index.d.cts CHANGED
@@ -1,9 +1,24 @@
1
1
  import { ModelInfo } from './model-registry.cjs';
2
- export { ContextWindowOptions, DEFAULT_MAX_VIDEO_BYTES, HIDDEN_PROVIDERS, MODELS, ModelBilling, clearRuntimeModels, getAllModels, getAuthStorageKey, getAuthStorageKeys, getContextWindow, getDefaultModel, getDefaultThinkingLevel, getListedModels, getMaxThinkingLevel, getModel, getModelsForProvider, getSummaryModel, getToolResultCharLimit, getVideoByteLimit, isHiddenProvider, isPaidModel, registerRuntimeModels, usesOpenAICodexTransport, withoutPaidTier } from './model-registry.cjs';
2
+ export { ContextWindowOptions, DEFAULT_MAX_VIDEO_BYTES, HIDDEN_PROVIDERS, MODELS, ModelBilling, clearRuntimeModels, getAllModels, getAuthStorageKey, getAuthStorageKeys, getContextWindow, getDefaultModel, getDefaultThinkingLevel, getListedModels, getMaxThinkingLevel, getModel, getModelsForProvider, getProviderCatalog, getSummaryModel, getToolResultCharLimit, getVideoByteLimit, isHiddenProvider, isPaidModel, registerRuntimeModels, setProviderCatalog, usesOpenAICodexTransport, withoutPaidTier } from './model-registry.cjs';
3
3
  import { ThinkingLevel, Provider } from '@kenkaiiii/gg-ai';
4
4
  export { getClaudeCliUserAgent, getClaudeCodeVersion, pendingClaudeCodeVersionRefresh } from '@kenkaiiii/gg-ai';
5
5
  export { AppPaths, getAppPaths } from './paths.cjs';
6
6
 
7
+ /** gg-ai's OPENROUTER_BASE_URL — where the openrouter transport goes with no override. */
8
+ declare const OPENROUTER_DEFAULT_BASE_URL = "https://openrouter.ai/api/v1";
9
+ interface ParsedOpenRouterCatalog {
10
+ models: ModelInfo[];
11
+ /** Rows dropped because they can't call tools (the agent needs tools) or are malformed. */
12
+ skipped: number;
13
+ }
14
+ /**
15
+ * Turn an OpenRouter-style `/models` body into registry rows. Field mapping is
16
+ * the live schema: tools from `supported_parameters`, image input from
17
+ * `architecture.input_modalities`, the effort ladder from
18
+ * `reasoning.supported_efforts`, output cap from `top_provider`.
19
+ */
20
+ declare function parseOpenRouterCatalog(body: unknown): ParsedOpenRouterCatalog;
21
+
7
22
  declare function getSupportedThinkingLevels(provider: Provider, model: string): readonly ThinkingLevel[];
8
23
  /**
9
24
  * The lowest effort `model` accepts — the first rung of its ladder, never
@@ -40,6 +55,8 @@ interface LocalEndpoint {
40
55
  apiKey?: string;
41
56
  /** True for endpoints the user added by hand (removable). */
42
57
  custom?: boolean;
58
+ /** User-pinned context window; wins over whatever the server reports. */
59
+ contextLength?: number;
43
60
  }
44
61
  /** One model as reported (and enriched) by a local server. */
45
62
  interface LocalModel {
@@ -304,7 +321,12 @@ declare class AuthStorage {
304
321
  private snapshotIno;
305
322
  /** Per-provider lock to serialize concurrent refresh calls. */
306
323
  private refreshLocks;
307
- constructor(filePath?: string);
324
+ private readonly detectMiniMaxRegion;
325
+ private readonly detectXiaomiCluster;
326
+ constructor(filePath?: string, options?: {
327
+ detectMiniMaxBaseUrl?: (apiKey: string) => Promise<string | undefined>;
328
+ detectXiaomiTokenPlanBaseUrl?: (apiKey: string) => Promise<string | undefined>;
329
+ });
308
330
  /** Path to the on-disk auth file. Useful for status output. */
309
331
  get path(): string;
310
332
  /** List provider keys with stored credentials. */
@@ -379,7 +401,21 @@ declare class AuthStorage {
379
401
  private mutateLatest;
380
402
  private reloadLatest;
381
403
  getCredentials(provider: string): Promise<OAuthCredentials | undefined>;
404
+ /**
405
+ * A MiniMax key saved without an endpoint (every key, until its first use)
406
+ * gets the endpoint of the region that issued it, saved so the check runs
407
+ * once. Without this a Mainland China key went to the Global API, got a 401,
408
+ * and was deleted as invalid.
409
+ */
410
+ private withMiniMaxRegion;
382
411
  setCredentials(provider: string, creds: OAuthCredentials): Promise<void>;
412
+ /**
413
+ * After a 401, move a regional key to the cluster that issued it instead of
414
+ * treating it as invalid. Only the Xiaomi Token Plan is regional: every key
415
+ * used to go to Singapore, so Europe and China keys were rejected and deleted.
416
+ * Returns the new base URL, or undefined when no other cluster accepts the key.
417
+ */
418
+ relocateRegionalApiKey(storageKeys: string[]): Promise<string | undefined>;
383
419
  clearRejectedApiKey(storageKey: string): Promise<boolean>;
384
420
  clearCredentials(provider: string): Promise<void>;
385
421
  /**
@@ -430,6 +466,41 @@ declare class NotLoggedInError extends Error {
430
466
  constructor(provider: string);
431
467
  }
432
468
 
469
+ /**
470
+ * MiniMax runs two separate platforms, and a key only works on the one that
471
+ * issued it: Global (platform.minimax.io) or Mainland China
472
+ * (platform.minimaxi.com). The user's location doesn't matter. Sending a key to
473
+ * the other region's API is rejected as an invalid key.
474
+ */
475
+ declare const MINIMAX_GLOBAL_BASE_URL = "https://api.minimax.io/anthropic";
476
+ declare const MINIMAX_CN_BASE_URL = "https://api.minimax.cn/anthropic";
477
+ /**
478
+ * The Anthropic-compatible base URL for the region that issued `apiKey`, found
479
+ * by asking both regions about the key. Undefined when neither region gives a
480
+ * clear answer (offline, timeouts) — callers then keep the Global default and
481
+ * may ask again later.
482
+ */
483
+ declare function detectMiniMaxBaseUrl(apiKey: string, options?: {
484
+ fetch?: typeof fetch;
485
+ timeoutMs?: number;
486
+ }): Promise<string | undefined>;
487
+
488
+ /**
489
+ * Xiaomi MiMo Token Plan runs separate clusters, and a `tp-` key only works on
490
+ * the cluster that issued it (shown on the user's Token Plan page). Any other
491
+ * cluster answers 401 "Invalid API Key". Pay-as-you-go (API Credits) keys use
492
+ * the single global host and are unaffected.
493
+ */
494
+ declare const XIAOMI_TOKEN_PLAN_BASE_URLS: readonly ["https://token-plan-sgp.xiaomimimo.com/v1", "https://token-plan-ams.xiaomimimo.com/v1", "https://token-plan-cn.xiaomimimo.com/v1"];
495
+ /**
496
+ * The Token Plan base URL whose cluster accepts `apiKey`, found by listing
497
+ * models (free, auth-only) on every cluster. Undefined when none accepts it.
498
+ */
499
+ declare function detectXiaomiTokenPlanBaseUrl(apiKey: string, options?: {
500
+ fetch?: typeof fetch;
501
+ timeoutMs?: number;
502
+ }): Promise<string | undefined>;
503
+
433
504
  type AuthMethod = "oauth" | "apikey";
434
505
  /**
435
506
  * One API-key option for a provider that splits auth across multiple distinct
@@ -836,4 +907,4 @@ interface AutoUpdater {
836
907
  }
837
908
  declare function createAutoUpdater(config: AutoUpdateConfig): AutoUpdater;
838
909
 
839
- export { AUTH_PROVIDERS, type ApiKeyVariant, type AuthMethod, type AuthMethodMeta, type AuthProviderMeta, AuthStorage, type AutoUpdateConfig, type AutoUpdater, DEFAULT_LOCAL_ENDPOINTS, type DiscoverOptions, type DiscoveryResult, type DualAuthProvider, FALLBACK_CONTEXT_WINDOW, GEMINI_API_KEY, GEMINI_API_KEY_BASE_URL, type InlineButton, LOCAL_API_KEY_PLACEHOLDER, LOCAL_AUTH_KEY_PREFIX, type LocalEndpoint, type LocalEndpointKind, type LocalEndpointProbe, type LocalModel, type LogLevel, MOONSHOT_OAUTH_KEY, ModelInfo, NotLoggedInError, type OAuthCredentials, type OAuthLoginCallbacks, PLAN_MODE_THINKING_CAP, type ProbeOptions, type ProgressCallback, SubscriptionUsageError, type SubscriptionUsageProvider, type SubscriptionUsageSnapshot, type SubscriptionUsageWindow, TelegramBot, type TelegramConfig, type TelegramMessage, type TelegramUpdate, type TelegramVoiceMessage, XAI_OAUTH_KEY, XIAOMI_CREDITS_KEY, authPriorityNote, clampThinkingForPlanMode, clearLocalDiscoveryCache, closeLogger, createAutoUpdater, decodeOggOpus, describeAuthMethods, discoverLocalModels, downmixToMono, dualAuthProvider, dualAuthProviderByOAuthKey, endpointRoot, fetchSubscriptionUsage, findProbedModel, formatLocalModelId, generatePKCE, getAuthProvider, getLowestThinkingLevel, getNextThinkingLevel, getSessionId, getSupportedThinkingLevels, grokCliBaseUrl, grokCliHeaders, isGrokCliEndpoint, isKimiCodingEndpoint, isLocalModelId, isLoggerOpen, isModelLoaded, isThinkingLevelSupported, kimiCodeBaseUrl, kimiCodingHeaders, localAuthStorageKey, localModelShortName, log, loginAnthropic, loginGemini, loginKimi, loginOpenAI, loginXai, oauthStorageKey, ollamaServedContext, openLog, parseLocalModelId, probeEndpoint, providerStorageKeys, readStoredBaseUrlSync, refreshAnthropicToken, refreshGeminiToken, refreshKimiToken, refreshOpenAIToken, refreshXaiToken, registerLogCleanup, resample, setProgressCallback, toModelInfo, transcribeVoice, withFileLock };
910
+ export { AUTH_PROVIDERS, type ApiKeyVariant, type AuthMethod, type AuthMethodMeta, type AuthProviderMeta, AuthStorage, type AutoUpdateConfig, type AutoUpdater, DEFAULT_LOCAL_ENDPOINTS, type DiscoverOptions, type DiscoveryResult, type DualAuthProvider, FALLBACK_CONTEXT_WINDOW, GEMINI_API_KEY, GEMINI_API_KEY_BASE_URL, type InlineButton, LOCAL_API_KEY_PLACEHOLDER, LOCAL_AUTH_KEY_PREFIX, type LocalEndpoint, type LocalEndpointKind, type LocalEndpointProbe, type LocalModel, type LogLevel, MINIMAX_CN_BASE_URL, MINIMAX_GLOBAL_BASE_URL, MOONSHOT_OAUTH_KEY, ModelInfo, NotLoggedInError, type OAuthCredentials, type OAuthLoginCallbacks, OPENROUTER_DEFAULT_BASE_URL, PLAN_MODE_THINKING_CAP, type ParsedOpenRouterCatalog, type ProbeOptions, type ProgressCallback, SubscriptionUsageError, type SubscriptionUsageProvider, type SubscriptionUsageSnapshot, type SubscriptionUsageWindow, TelegramBot, type TelegramConfig, type TelegramMessage, type TelegramUpdate, type TelegramVoiceMessage, XAI_OAUTH_KEY, XIAOMI_CREDITS_KEY, XIAOMI_TOKEN_PLAN_BASE_URLS, authPriorityNote, clampThinkingForPlanMode, clearLocalDiscoveryCache, closeLogger, createAutoUpdater, decodeOggOpus, describeAuthMethods, detectMiniMaxBaseUrl, detectXiaomiTokenPlanBaseUrl, discoverLocalModels, downmixToMono, dualAuthProvider, dualAuthProviderByOAuthKey, endpointRoot, fetchSubscriptionUsage, findProbedModel, formatLocalModelId, generatePKCE, getAuthProvider, getLowestThinkingLevel, getNextThinkingLevel, getSessionId, getSupportedThinkingLevels, grokCliBaseUrl, grokCliHeaders, isGrokCliEndpoint, isKimiCodingEndpoint, isLocalModelId, isLoggerOpen, isModelLoaded, isThinkingLevelSupported, kimiCodeBaseUrl, kimiCodingHeaders, localAuthStorageKey, localModelShortName, log, loginAnthropic, loginGemini, loginKimi, loginOpenAI, loginXai, oauthStorageKey, ollamaServedContext, openLog, parseLocalModelId, parseOpenRouterCatalog, probeEndpoint, providerStorageKeys, readStoredBaseUrlSync, refreshAnthropicToken, refreshGeminiToken, refreshKimiToken, refreshOpenAIToken, refreshXaiToken, registerLogCleanup, resample, setProgressCallback, toModelInfo, transcribeVoice, withFileLock };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,24 @@
1
1
  import { ModelInfo } from './model-registry.js';
2
- export { ContextWindowOptions, DEFAULT_MAX_VIDEO_BYTES, HIDDEN_PROVIDERS, MODELS, ModelBilling, clearRuntimeModels, getAllModels, getAuthStorageKey, getAuthStorageKeys, getContextWindow, getDefaultModel, getDefaultThinkingLevel, getListedModels, getMaxThinkingLevel, getModel, getModelsForProvider, getSummaryModel, getToolResultCharLimit, getVideoByteLimit, isHiddenProvider, isPaidModel, registerRuntimeModels, usesOpenAICodexTransport, withoutPaidTier } from './model-registry.js';
2
+ export { ContextWindowOptions, DEFAULT_MAX_VIDEO_BYTES, HIDDEN_PROVIDERS, MODELS, ModelBilling, clearRuntimeModels, getAllModels, getAuthStorageKey, getAuthStorageKeys, getContextWindow, getDefaultModel, getDefaultThinkingLevel, getListedModels, getMaxThinkingLevel, getModel, getModelsForProvider, getProviderCatalog, getSummaryModel, getToolResultCharLimit, getVideoByteLimit, isHiddenProvider, isPaidModel, registerRuntimeModels, setProviderCatalog, usesOpenAICodexTransport, withoutPaidTier } from './model-registry.js';
3
3
  import { ThinkingLevel, Provider } from '@kenkaiiii/gg-ai';
4
4
  export { getClaudeCliUserAgent, getClaudeCodeVersion, pendingClaudeCodeVersionRefresh } from '@kenkaiiii/gg-ai';
5
5
  export { AppPaths, getAppPaths } from './paths.js';
6
6
 
7
+ /** gg-ai's OPENROUTER_BASE_URL — where the openrouter transport goes with no override. */
8
+ declare const OPENROUTER_DEFAULT_BASE_URL = "https://openrouter.ai/api/v1";
9
+ interface ParsedOpenRouterCatalog {
10
+ models: ModelInfo[];
11
+ /** Rows dropped because they can't call tools (the agent needs tools) or are malformed. */
12
+ skipped: number;
13
+ }
14
+ /**
15
+ * Turn an OpenRouter-style `/models` body into registry rows. Field mapping is
16
+ * the live schema: tools from `supported_parameters`, image input from
17
+ * `architecture.input_modalities`, the effort ladder from
18
+ * `reasoning.supported_efforts`, output cap from `top_provider`.
19
+ */
20
+ declare function parseOpenRouterCatalog(body: unknown): ParsedOpenRouterCatalog;
21
+
7
22
  declare function getSupportedThinkingLevels(provider: Provider, model: string): readonly ThinkingLevel[];
8
23
  /**
9
24
  * The lowest effort `model` accepts — the first rung of its ladder, never
@@ -40,6 +55,8 @@ interface LocalEndpoint {
40
55
  apiKey?: string;
41
56
  /** True for endpoints the user added by hand (removable). */
42
57
  custom?: boolean;
58
+ /** User-pinned context window; wins over whatever the server reports. */
59
+ contextLength?: number;
43
60
  }
44
61
  /** One model as reported (and enriched) by a local server. */
45
62
  interface LocalModel {
@@ -304,7 +321,12 @@ declare class AuthStorage {
304
321
  private snapshotIno;
305
322
  /** Per-provider lock to serialize concurrent refresh calls. */
306
323
  private refreshLocks;
307
- constructor(filePath?: string);
324
+ private readonly detectMiniMaxRegion;
325
+ private readonly detectXiaomiCluster;
326
+ constructor(filePath?: string, options?: {
327
+ detectMiniMaxBaseUrl?: (apiKey: string) => Promise<string | undefined>;
328
+ detectXiaomiTokenPlanBaseUrl?: (apiKey: string) => Promise<string | undefined>;
329
+ });
308
330
  /** Path to the on-disk auth file. Useful for status output. */
309
331
  get path(): string;
310
332
  /** List provider keys with stored credentials. */
@@ -379,7 +401,21 @@ declare class AuthStorage {
379
401
  private mutateLatest;
380
402
  private reloadLatest;
381
403
  getCredentials(provider: string): Promise<OAuthCredentials | undefined>;
404
+ /**
405
+ * A MiniMax key saved without an endpoint (every key, until its first use)
406
+ * gets the endpoint of the region that issued it, saved so the check runs
407
+ * once. Without this a Mainland China key went to the Global API, got a 401,
408
+ * and was deleted as invalid.
409
+ */
410
+ private withMiniMaxRegion;
382
411
  setCredentials(provider: string, creds: OAuthCredentials): Promise<void>;
412
+ /**
413
+ * After a 401, move a regional key to the cluster that issued it instead of
414
+ * treating it as invalid. Only the Xiaomi Token Plan is regional: every key
415
+ * used to go to Singapore, so Europe and China keys were rejected and deleted.
416
+ * Returns the new base URL, or undefined when no other cluster accepts the key.
417
+ */
418
+ relocateRegionalApiKey(storageKeys: string[]): Promise<string | undefined>;
383
419
  clearRejectedApiKey(storageKey: string): Promise<boolean>;
384
420
  clearCredentials(provider: string): Promise<void>;
385
421
  /**
@@ -430,6 +466,41 @@ declare class NotLoggedInError extends Error {
430
466
  constructor(provider: string);
431
467
  }
432
468
 
469
+ /**
470
+ * MiniMax runs two separate platforms, and a key only works on the one that
471
+ * issued it: Global (platform.minimax.io) or Mainland China
472
+ * (platform.minimaxi.com). The user's location doesn't matter. Sending a key to
473
+ * the other region's API is rejected as an invalid key.
474
+ */
475
+ declare const MINIMAX_GLOBAL_BASE_URL = "https://api.minimax.io/anthropic";
476
+ declare const MINIMAX_CN_BASE_URL = "https://api.minimax.cn/anthropic";
477
+ /**
478
+ * The Anthropic-compatible base URL for the region that issued `apiKey`, found
479
+ * by asking both regions about the key. Undefined when neither region gives a
480
+ * clear answer (offline, timeouts) — callers then keep the Global default and
481
+ * may ask again later.
482
+ */
483
+ declare function detectMiniMaxBaseUrl(apiKey: string, options?: {
484
+ fetch?: typeof fetch;
485
+ timeoutMs?: number;
486
+ }): Promise<string | undefined>;
487
+
488
+ /**
489
+ * Xiaomi MiMo Token Plan runs separate clusters, and a `tp-` key only works on
490
+ * the cluster that issued it (shown on the user's Token Plan page). Any other
491
+ * cluster answers 401 "Invalid API Key". Pay-as-you-go (API Credits) keys use
492
+ * the single global host and are unaffected.
493
+ */
494
+ declare const XIAOMI_TOKEN_PLAN_BASE_URLS: readonly ["https://token-plan-sgp.xiaomimimo.com/v1", "https://token-plan-ams.xiaomimimo.com/v1", "https://token-plan-cn.xiaomimimo.com/v1"];
495
+ /**
496
+ * The Token Plan base URL whose cluster accepts `apiKey`, found by listing
497
+ * models (free, auth-only) on every cluster. Undefined when none accepts it.
498
+ */
499
+ declare function detectXiaomiTokenPlanBaseUrl(apiKey: string, options?: {
500
+ fetch?: typeof fetch;
501
+ timeoutMs?: number;
502
+ }): Promise<string | undefined>;
503
+
433
504
  type AuthMethod = "oauth" | "apikey";
434
505
  /**
435
506
  * One API-key option for a provider that splits auth across multiple distinct
@@ -836,4 +907,4 @@ interface AutoUpdater {
836
907
  }
837
908
  declare function createAutoUpdater(config: AutoUpdateConfig): AutoUpdater;
838
909
 
839
- export { AUTH_PROVIDERS, type ApiKeyVariant, type AuthMethod, type AuthMethodMeta, type AuthProviderMeta, AuthStorage, type AutoUpdateConfig, type AutoUpdater, DEFAULT_LOCAL_ENDPOINTS, type DiscoverOptions, type DiscoveryResult, type DualAuthProvider, FALLBACK_CONTEXT_WINDOW, GEMINI_API_KEY, GEMINI_API_KEY_BASE_URL, type InlineButton, LOCAL_API_KEY_PLACEHOLDER, LOCAL_AUTH_KEY_PREFIX, type LocalEndpoint, type LocalEndpointKind, type LocalEndpointProbe, type LocalModel, type LogLevel, MOONSHOT_OAUTH_KEY, ModelInfo, NotLoggedInError, type OAuthCredentials, type OAuthLoginCallbacks, PLAN_MODE_THINKING_CAP, type ProbeOptions, type ProgressCallback, SubscriptionUsageError, type SubscriptionUsageProvider, type SubscriptionUsageSnapshot, type SubscriptionUsageWindow, TelegramBot, type TelegramConfig, type TelegramMessage, type TelegramUpdate, type TelegramVoiceMessage, XAI_OAUTH_KEY, XIAOMI_CREDITS_KEY, authPriorityNote, clampThinkingForPlanMode, clearLocalDiscoveryCache, closeLogger, createAutoUpdater, decodeOggOpus, describeAuthMethods, discoverLocalModels, downmixToMono, dualAuthProvider, dualAuthProviderByOAuthKey, endpointRoot, fetchSubscriptionUsage, findProbedModel, formatLocalModelId, generatePKCE, getAuthProvider, getLowestThinkingLevel, getNextThinkingLevel, getSessionId, getSupportedThinkingLevels, grokCliBaseUrl, grokCliHeaders, isGrokCliEndpoint, isKimiCodingEndpoint, isLocalModelId, isLoggerOpen, isModelLoaded, isThinkingLevelSupported, kimiCodeBaseUrl, kimiCodingHeaders, localAuthStorageKey, localModelShortName, log, loginAnthropic, loginGemini, loginKimi, loginOpenAI, loginXai, oauthStorageKey, ollamaServedContext, openLog, parseLocalModelId, probeEndpoint, providerStorageKeys, readStoredBaseUrlSync, refreshAnthropicToken, refreshGeminiToken, refreshKimiToken, refreshOpenAIToken, refreshXaiToken, registerLogCleanup, resample, setProgressCallback, toModelInfo, transcribeVoice, withFileLock };
910
+ export { AUTH_PROVIDERS, type ApiKeyVariant, type AuthMethod, type AuthMethodMeta, type AuthProviderMeta, AuthStorage, type AutoUpdateConfig, type AutoUpdater, DEFAULT_LOCAL_ENDPOINTS, type DiscoverOptions, type DiscoveryResult, type DualAuthProvider, FALLBACK_CONTEXT_WINDOW, GEMINI_API_KEY, GEMINI_API_KEY_BASE_URL, type InlineButton, LOCAL_API_KEY_PLACEHOLDER, LOCAL_AUTH_KEY_PREFIX, type LocalEndpoint, type LocalEndpointKind, type LocalEndpointProbe, type LocalModel, type LogLevel, MINIMAX_CN_BASE_URL, MINIMAX_GLOBAL_BASE_URL, MOONSHOT_OAUTH_KEY, ModelInfo, NotLoggedInError, type OAuthCredentials, type OAuthLoginCallbacks, OPENROUTER_DEFAULT_BASE_URL, PLAN_MODE_THINKING_CAP, type ParsedOpenRouterCatalog, type ProbeOptions, type ProgressCallback, SubscriptionUsageError, type SubscriptionUsageProvider, type SubscriptionUsageSnapshot, type SubscriptionUsageWindow, TelegramBot, type TelegramConfig, type TelegramMessage, type TelegramUpdate, type TelegramVoiceMessage, XAI_OAUTH_KEY, XIAOMI_CREDITS_KEY, XIAOMI_TOKEN_PLAN_BASE_URLS, authPriorityNote, clampThinkingForPlanMode, clearLocalDiscoveryCache, closeLogger, createAutoUpdater, decodeOggOpus, describeAuthMethods, detectMiniMaxBaseUrl, detectXiaomiTokenPlanBaseUrl, discoverLocalModels, downmixToMono, dualAuthProvider, dualAuthProviderByOAuthKey, endpointRoot, fetchSubscriptionUsage, findProbedModel, formatLocalModelId, generatePKCE, getAuthProvider, getLowestThinkingLevel, getNextThinkingLevel, getSessionId, getSupportedThinkingLevels, grokCliBaseUrl, grokCliHeaders, isGrokCliEndpoint, isKimiCodingEndpoint, isLocalModelId, isLoggerOpen, isModelLoaded, isThinkingLevelSupported, kimiCodeBaseUrl, kimiCodingHeaders, localAuthStorageKey, localModelShortName, log, loginAnthropic, loginGemini, loginKimi, loginOpenAI, loginXai, oauthStorageKey, ollamaServedContext, openLog, parseLocalModelId, parseOpenRouterCatalog, probeEndpoint, providerStorageKeys, readStoredBaseUrlSync, refreshAnthropicToken, refreshGeminiToken, refreshKimiToken, refreshOpenAIToken, refreshXaiToken, registerLogCleanup, resample, setProgressCallback, toModelInfo, transcribeVoice, withFileLock };
package/dist/index.js CHANGED
@@ -5,13 +5,18 @@ import {
5
5
  GEMINI_API_KEY_BASE_URL,
6
6
  HIDDEN_PROVIDERS,
7
7
  LOCAL_AUTH_KEY_PREFIX,
8
+ MINIMAX_CN_BASE_URL,
9
+ MINIMAX_GLOBAL_BASE_URL,
8
10
  MODELS,
9
11
  MOONSHOT_OAUTH_KEY,
10
12
  NotLoggedInError,
11
13
  XAI_OAUTH_KEY,
12
14
  XIAOMI_CREDITS_KEY,
15
+ XIAOMI_TOKEN_PLAN_BASE_URLS,
13
16
  clearRuntimeModels,
14
17
  closeLogger,
18
+ detectMiniMaxBaseUrl,
19
+ detectXiaomiTokenPlanBaseUrl,
15
20
  dualAuthProvider,
16
21
  dualAuthProviderByOAuthKey,
17
22
  generatePKCE,
@@ -27,6 +32,7 @@ import {
27
32
  getMaxThinkingLevel,
28
33
  getModel,
29
34
  getModelsForProvider,
35
+ getProviderCatalog,
30
36
  getSessionId,
31
37
  getSummaryModel,
32
38
  getToolResultCharLimit,
@@ -58,14 +64,68 @@ import {
58
64
  refreshXaiToken,
59
65
  registerLogCleanup,
60
66
  registerRuntimeModels,
67
+ setProviderCatalog,
61
68
  usesOpenAICodexTransport,
62
69
  withFileLock,
63
70
  withoutPaidTier
64
- } from "./chunk-QL5357JB.js";
71
+ } from "./chunk-YXPGQIOD.js";
65
72
  import {
66
73
  getAppPaths
67
74
  } from "./chunk-2X5L6U4Z.js";
68
75
 
76
+ // src/openrouter-catalog.ts
77
+ var OPENROUTER_DEFAULT_BASE_URL = "https://openrouter.ai/api/v1";
78
+ var EFFORT_LADDER = ["low", "medium", "high", "xhigh", "max"];
79
+ function positiveInt(value) {
80
+ return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : void 0;
81
+ }
82
+ function strings(value) {
83
+ return Array.isArray(value) ? value.filter((v) => typeof v === "string") : [];
84
+ }
85
+ function costTier(prompt) {
86
+ const perToken = typeof prompt === "string" ? Number(prompt) : NaN;
87
+ if (!Number.isFinite(perToken) || perToken < 5e-7) return "low";
88
+ return perToken < 3e-6 ? "medium" : "high";
89
+ }
90
+ function parseOpenRouterCatalog(body) {
91
+ const data = body?.data;
92
+ if (!Array.isArray(data)) return { models: [], skipped: 0 };
93
+ const models = [];
94
+ let skipped = 0;
95
+ const seen = /* @__PURE__ */ new Set();
96
+ for (const raw of data) {
97
+ const id = typeof raw?.id === "string" ? raw.id.trim() : "";
98
+ const params = strings(raw?.supported_parameters);
99
+ const contextWindow = positiveInt(raw?.top_provider?.context_length) ?? positiveInt(raw?.context_length);
100
+ if (!id || seen.has(id) || !params.includes("tools") || !contextWindow) {
101
+ skipped++;
102
+ continue;
103
+ }
104
+ seen.add(id);
105
+ const efforts = strings(raw.reasoning?.supported_efforts);
106
+ const ladder = EFFORT_LADDER.filter((rung) => efforts.includes(rung));
107
+ const supportsThinking = ladder.length > 0 || params.includes("reasoning") || params.includes("reasoning_effort");
108
+ const defaultEffort = raw.reasoning?.default_effort;
109
+ const maxOutput = positiveInt(raw.top_provider?.max_completion_tokens) ?? Math.min(contextWindow, 16384);
110
+ models.push({
111
+ id,
112
+ name: typeof raw.name === "string" && raw.name.trim() ? raw.name.trim() : id,
113
+ provider: "openrouter",
114
+ contextWindow,
115
+ maxOutputTokens: Math.min(maxOutput, contextWindow),
116
+ supportsThinking,
117
+ supportsImages: strings(raw.architecture?.input_modalities).includes("image"),
118
+ // Video needs a per-transport payload cap the catalog doesn't publish.
119
+ supportsVideo: false,
120
+ costTier: costTier(raw.pricing?.prompt),
121
+ maxThinkingLevel: ladder[ladder.length - 1] ?? "high",
122
+ ...ladder.length > 0 ? { thinkingLevels: ladder } : {},
123
+ ...typeof defaultEffort === "string" && ladder.includes(defaultEffort) ? { defaultThinkingLevel: defaultEffort } : {}
124
+ });
125
+ }
126
+ return { models, skipped };
127
+ }
128
+
69
129
  // src/thinking-level.ts
70
130
  var OPENAI_GPT_THINKING_LEVELS = ["medium", "high", "xhigh"];
71
131
  var OPENAI_GPT_56_THINKING_LEVELS = [
@@ -94,6 +154,13 @@ var ANTHROPIC_ADAPTIVE_THINKING_LEVELS = [
94
154
  ];
95
155
  var MOONSHOT_K3_THINKING_LEVELS = ["low", "high", "max"];
96
156
  var GLM_THINKING_LEVELS = ["low", "medium", "high", "xhigh", "max"];
157
+ var MINIMAX_EFFORT_THINKING_LEVELS = [
158
+ "low",
159
+ "medium",
160
+ "high",
161
+ "xhigh",
162
+ "max"
163
+ ];
97
164
  var LOCAL_THINKING_LEVELS = ["low", "medium", "high", "max"];
98
165
  function isOpenAIGptModel(provider, model) {
99
166
  return provider === "openai" && model.startsWith("gpt-");
@@ -110,6 +177,9 @@ function isMoonshotK3Model(provider, model) {
110
177
  function isGlmModel(provider) {
111
178
  return provider === "glm";
112
179
  }
180
+ function isMiniMaxEffortModel(provider, model) {
181
+ return provider === "minimax" && model.startsWith("MiniMax-M3.1");
182
+ }
113
183
  function isAnthropicXhighModel(provider, model) {
114
184
  return provider === "anthropic" && /opus-5|opus-4-8|opus-4-7|sonnet-5[-.]5|haiku-5[-.]5/.test(model);
115
185
  }
@@ -123,6 +193,8 @@ function getSupportedThinkingLevels(provider, model) {
123
193
  const maxIndex2 = LOCAL_THINKING_LEVELS.indexOf(info.maxThinkingLevel);
124
194
  return maxIndex2 === -1 ? LOCAL_THINKING_LEVELS.slice(0, 3) : LOCAL_THINKING_LEVELS.slice(0, maxIndex2 + 1);
125
195
  }
196
+ const declared = getModel(model)?.thinkingLevels;
197
+ if (declared && declared.length > 0) return declared;
126
198
  const maxLevel = getMaxThinkingLevel(model);
127
199
  if (isAnthropicAdaptiveModel(provider, model)) {
128
200
  const levels2 = isAnthropicXhighModel(provider, model) ? ANTHROPIC_XHIGH_THINKING_LEVELS : ANTHROPIC_ADAPTIVE_THINKING_LEVELS;
@@ -142,6 +214,7 @@ function getSupportedThinkingLevels(provider, model) {
142
214
  }
143
215
  if (isMoonshotK3Model(provider, model)) return MOONSHOT_K3_THINKING_LEVELS;
144
216
  if (provider === "deepseek") return DEEPSEEK_THINKING_LEVELS;
217
+ if (isMiniMaxEffortModel(provider, model)) return MINIMAX_EFFORT_THINKING_LEVELS;
145
218
  if (isGlmModel(provider)) {
146
219
  const maxIndex2 = GLM_THINKING_LEVELS.indexOf(maxLevel);
147
220
  if (maxIndex2 === -1) return GLM_THINKING_LEVELS;
@@ -162,7 +235,7 @@ function isThinkingLevelSupported(provider, model, level) {
162
235
  }
163
236
  function getNextThinkingLevel(provider, model, current) {
164
237
  const supportedLevels = getSupportedThinkingLevels(provider, model);
165
- 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
238
+ 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
166
239
  // low/medium/high on `reasoning_effort` (verified against 0.32) and the
167
240
  // other OpenAI-compatible servers use the same three. A model that can't
168
241
  // reason at all already has no supported levels, so it never gets here.
@@ -277,7 +350,9 @@ async function probeEndpoint(endpoint, { timeoutMs = DEFAULT_PROBE_TIMEOUT_MS, s
277
350
  const entries = (list.data ?? []).filter(
278
351
  (entry) => typeof entry.id === "string" && entry.id.length > 0 && !NON_CHAT_ID_PATTERN.test(entry.id)
279
352
  );
280
- const models = await enrich(endpoint, entries, { timeoutMs, signal });
353
+ const enriched = await enrich(endpoint, entries, { timeoutMs, signal });
354
+ const pinned = contextLength(endpoint.contextLength);
355
+ const models = pinned === void 0 ? enriched : enriched.map((m) => ({ ...m, contextWindow: pinned, contextWindowKnown: true }));
281
356
  log("INFO", "local-models", `Probed ${endpoint.label}`, {
282
357
  baseUrl: endpoint.baseUrl,
283
358
  models: String(models.length)
@@ -303,7 +378,7 @@ async function enrichCustom(endpoint, entries, options) {
303
378
  return generic;
304
379
  }
305
380
  function genericModel(endpoint, entry) {
306
- const declared = contextLength(entry.max_model_len) ?? contextLength(entry.context_length);
381
+ const declared = contextLength(entry.max_model_len) ?? contextLength(entry.context_length) ?? contextLength(entry.meta?.n_ctx);
307
382
  return {
308
383
  rawId: entry.id,
309
384
  endpointId: endpoint.id,
@@ -483,7 +558,7 @@ function toModelInfo(model, endpoint) {
483
558
  }
484
559
  var cache;
485
560
  function cacheKey(endpoints) {
486
- return endpoints.map((e) => `${e.id}@${e.baseUrl}`).join("|");
561
+ return endpoints.map((e) => `${e.id}@${e.baseUrl}#${e.contextLength ?? ""}`).join("|");
487
562
  }
488
563
  async function discoverLocalModels(endpoints = DEFAULT_LOCAL_ENDPOINTS, options = {}) {
489
564
  const key = cacheKey(endpoints);
@@ -604,7 +679,7 @@ var ALL_AUTH_PROVIDERS = [
604
679
  {
605
680
  value: "minimax",
606
681
  label: "MiniMax",
607
- description: "MiniMax M3",
682
+ description: "MiniMax M3.1 Flash, M3",
608
683
  methods: ["apikey"],
609
684
  apiKeyLabel: "MiniMax"
610
685
  },
@@ -1436,14 +1511,18 @@ export {
1436
1511
  HIDDEN_PROVIDERS,
1437
1512
  LOCAL_API_KEY_PLACEHOLDER,
1438
1513
  LOCAL_AUTH_KEY_PREFIX,
1514
+ MINIMAX_CN_BASE_URL,
1515
+ MINIMAX_GLOBAL_BASE_URL,
1439
1516
  MODELS,
1440
1517
  MOONSHOT_OAUTH_KEY,
1441
1518
  NotLoggedInError,
1519
+ OPENROUTER_DEFAULT_BASE_URL,
1442
1520
  PLAN_MODE_THINKING_CAP,
1443
1521
  SubscriptionUsageError,
1444
1522
  TelegramBot,
1445
1523
  XAI_OAUTH_KEY,
1446
1524
  XIAOMI_CREDITS_KEY,
1525
+ XIAOMI_TOKEN_PLAN_BASE_URLS,
1447
1526
  authPriorityNote,
1448
1527
  clampThinkingForPlanMode,
1449
1528
  clearLocalDiscoveryCache,
@@ -1452,6 +1531,8 @@ export {
1452
1531
  createAutoUpdater,
1453
1532
  decodeOggOpus,
1454
1533
  describeAuthMethods,
1534
+ detectMiniMaxBaseUrl,
1535
+ detectXiaomiTokenPlanBaseUrl,
1455
1536
  discoverLocalModels,
1456
1537
  downmixToMono,
1457
1538
  dualAuthProvider,
@@ -1477,6 +1558,7 @@ export {
1477
1558
  getModel,
1478
1559
  getModelsForProvider,
1479
1560
  getNextThinkingLevel,
1561
+ getProviderCatalog,
1480
1562
  getSessionId,
1481
1563
  getSummaryModel,
1482
1564
  getSupportedThinkingLevels,
@@ -1506,6 +1588,7 @@ export {
1506
1588
  ollamaServedContext,
1507
1589
  openLog,
1508
1590
  parseLocalModelId,
1591
+ parseOpenRouterCatalog,
1509
1592
  pendingClaudeCodeVersionRefresh,
1510
1593
  probeEndpoint,
1511
1594
  providerStorageKeys,
@@ -1519,6 +1602,7 @@ export {
1519
1602
  registerRuntimeModels,
1520
1603
  resample,
1521
1604
  setProgressCallback,
1605
+ setProviderCatalog,
1522
1606
  toModelInfo,
1523
1607
  transcribeVoice,
1524
1608
  usesOpenAICodexTransport,