@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/index.d.cts CHANGED
@@ -27,23 +27,6 @@ declare const PLAN_MODE_THINKING_CAP: ThinkingLevel;
27
27
  * `undefined` (thinking off) and already-low levels. */
28
28
  declare function clampThinkingForPlanMode(level: ThinkingLevel | undefined): ThinkingLevel | undefined;
29
29
 
30
- /**
31
- * Local model discovery — Ollama, LM Studio, llama.cpp (`llama-server`), vLLM,
32
- * and any other OpenAI-compatible server the user points us at.
33
- *
34
- * Everything rides the OpenAI-compatible `/v1` transport (see the `local`
35
- * provider in gg-ai's stream.ts); the only per-server difference is where the
36
- * *capabilities* come from, because `GET /v1/models` reports nothing useful:
37
- *
38
- * - Ollama → `/api/show` + `/api/ps` → capabilities + running context
39
- * - LM Studio → `/api/v1/models` (v0 fallback) → capabilities + loaded context
40
- * - llama.cpp → `GET /props` → `default_generation_settings.n_ctx`
41
- * - vLLM/other → nothing; `max_model_len` sometimes rides the model object.
42
- *
43
- * Probing never throws: an unreachable server is a normal state (the user just
44
- * doesn't have it running), not an error to surface.
45
- */
46
-
47
30
  /** Which capability API a local endpoint speaks, beyond plain `/v1/models`. */
48
31
  type LocalEndpointKind = "ollama" | "lmstudio" | "llamacpp" | "vllm" | "custom";
49
32
  interface LocalEndpoint {
@@ -91,7 +74,7 @@ declare const DEFAULT_LOCAL_ENDPOINTS: readonly LocalEndpoint[];
91
74
  * auto-compaction already sailed past, while under-guessing only compacts early.
92
75
  */
93
76
  declare const FALLBACK_CONTEXT_WINDOW = 4096;
94
- /** Placeholder token for endpoints with no key — these servers ignore it. */
77
+ /** Token stored for endpoints with no key; never sent on the wire. */
95
78
  declare const LOCAL_API_KEY_PLACEHOLDER = "local";
96
79
  /**
97
80
  * `local/<endpointId>/<rawModelId>`. The raw id can itself contain slashes
@@ -102,6 +85,11 @@ declare function parseLocalModelId(id: string): {
102
85
  endpointId: string;
103
86
  rawId: string;
104
87
  } | undefined;
88
+ /**
89
+ * The model's own name, for a UI that shows the endpoint separately: the last
90
+ * segment of the raw id, so `minimax/minimax-m2:free` reads `minimax-m2:free`.
91
+ */
92
+ declare function localModelShortName(rawId: string): string;
105
93
  declare function isLocalModelId(id: string): boolean;
106
94
  /** Auth-storage key holding the credential (and baseUrl) for one local endpoint. */
107
95
  declare function localAuthStorageKey(endpointId: string): string;
@@ -117,6 +105,17 @@ interface ProbeOptions {
117
105
  * error toast.
118
106
  */
119
107
  declare function probeEndpoint(endpoint: LocalEndpoint, { timeoutMs, signal }?: ProbeOptions): Promise<LocalEndpointProbe>;
108
+ /**
109
+ * The context Ollama serves `rawId` with, read from `/api/ps`. With `load`, first
110
+ * loads the model the way a chat request would (default options), since an
111
+ * unloaded model's size is only decided at load time: the OpenAI endpoint
112
+ * ignores `num_ctx`, so this is the window the agent will really get.
113
+ */
114
+ declare function ollamaServedContext(endpoint: LocalEndpoint, rawId: string, { load, timeoutMs, signal, }?: {
115
+ load?: boolean;
116
+ timeoutMs?: number;
117
+ signal?: AbortSignal;
118
+ }): Promise<number | undefined>;
120
119
  /** Convert a probed local model into the registry shape the whole app speaks. */
121
120
  declare function toModelInfo(model: LocalModel, endpoint: LocalEndpoint): ModelInfo;
122
121
  interface DiscoveryResult {
@@ -305,7 +304,12 @@ declare class AuthStorage {
305
304
  private snapshotIno;
306
305
  /** Per-provider lock to serialize concurrent refresh calls. */
307
306
  private refreshLocks;
308
- constructor(filePath?: string);
307
+ private readonly detectMiniMaxRegion;
308
+ private readonly detectXiaomiCluster;
309
+ constructor(filePath?: string, options?: {
310
+ detectMiniMaxBaseUrl?: (apiKey: string) => Promise<string | undefined>;
311
+ detectXiaomiTokenPlanBaseUrl?: (apiKey: string) => Promise<string | undefined>;
312
+ });
309
313
  /** Path to the on-disk auth file. Useful for status output. */
310
314
  get path(): string;
311
315
  /** List provider keys with stored credentials. */
@@ -380,7 +384,22 @@ declare class AuthStorage {
380
384
  private mutateLatest;
381
385
  private reloadLatest;
382
386
  getCredentials(provider: string): Promise<OAuthCredentials | undefined>;
387
+ /**
388
+ * A MiniMax key saved without an endpoint (every key, until its first use)
389
+ * gets the endpoint of the region that issued it, saved so the check runs
390
+ * once. Without this a Mainland China key went to the Global API, got a 401,
391
+ * and was deleted as invalid.
392
+ */
393
+ private withMiniMaxRegion;
383
394
  setCredentials(provider: string, creds: OAuthCredentials): Promise<void>;
395
+ /**
396
+ * After a 401, move a regional key to the cluster that issued it instead of
397
+ * treating it as invalid. Only the Xiaomi Token Plan is regional: every key
398
+ * used to go to Singapore, so Europe and China keys were rejected and deleted.
399
+ * Returns the new base URL, or undefined when no other cluster accepts the key.
400
+ */
401
+ relocateRegionalApiKey(storageKeys: string[]): Promise<string | undefined>;
402
+ clearRejectedApiKey(storageKey: string): Promise<boolean>;
384
403
  clearCredentials(provider: string): Promise<void>;
385
404
  /**
386
405
  * Mark the credential stored under `storageKey` as usage-exhausted until
@@ -430,6 +449,41 @@ declare class NotLoggedInError extends Error {
430
449
  constructor(provider: string);
431
450
  }
432
451
 
452
+ /**
453
+ * MiniMax runs two separate platforms, and a key only works on the one that
454
+ * issued it: Global (platform.minimax.io) or Mainland China
455
+ * (platform.minimaxi.com). The user's location doesn't matter. Sending a key to
456
+ * the other region's API is rejected as an invalid key.
457
+ */
458
+ declare const MINIMAX_GLOBAL_BASE_URL = "https://api.minimax.io/anthropic";
459
+ declare const MINIMAX_CN_BASE_URL = "https://api.minimax.cn/anthropic";
460
+ /**
461
+ * The Anthropic-compatible base URL for the region that issued `apiKey`, found
462
+ * by asking both regions about the key. Undefined when neither region gives a
463
+ * clear answer (offline, timeouts) — callers then keep the Global default and
464
+ * may ask again later.
465
+ */
466
+ declare function detectMiniMaxBaseUrl(apiKey: string, options?: {
467
+ fetch?: typeof fetch;
468
+ timeoutMs?: number;
469
+ }): Promise<string | undefined>;
470
+
471
+ /**
472
+ * Xiaomi MiMo Token Plan runs separate clusters, and a `tp-` key only works on
473
+ * the cluster that issued it (shown on the user's Token Plan page). Any other
474
+ * cluster answers 401 "Invalid API Key". Pay-as-you-go (API Credits) keys use
475
+ * the single global host and are unaffected.
476
+ */
477
+ 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"];
478
+ /**
479
+ * The Token Plan base URL whose cluster accepts `apiKey`, found by listing
480
+ * models (free, auth-only) on every cluster. Undefined when none accepts it.
481
+ */
482
+ declare function detectXiaomiTokenPlanBaseUrl(apiKey: string, options?: {
483
+ fetch?: typeof fetch;
484
+ timeoutMs?: number;
485
+ }): Promise<string | undefined>;
486
+
433
487
  type AuthMethod = "oauth" | "apikey";
434
488
  /**
435
489
  * One API-key option for a provider that splits auth across multiple distinct
@@ -836,4 +890,4 @@ interface AutoUpdater {
836
890
  }
837
891
  declare function createAutoUpdater(config: AutoUpdateConfig): AutoUpdater;
838
892
 
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, log, loginAnthropic, loginGemini, loginKimi, loginOpenAI, loginXai, oauthStorageKey, openLog, parseLocalModelId, probeEndpoint, providerStorageKeys, readStoredBaseUrlSync, refreshAnthropicToken, refreshGeminiToken, refreshKimiToken, refreshOpenAIToken, refreshXaiToken, registerLogCleanup, resample, setProgressCallback, toModelInfo, transcribeVoice, withFileLock };
893
+ 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, 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, 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, probeEndpoint, providerStorageKeys, readStoredBaseUrlSync, refreshAnthropicToken, refreshGeminiToken, refreshKimiToken, refreshOpenAIToken, refreshXaiToken, registerLogCleanup, resample, setProgressCallback, toModelInfo, transcribeVoice, withFileLock };
package/dist/index.d.ts CHANGED
@@ -27,23 +27,6 @@ declare const PLAN_MODE_THINKING_CAP: ThinkingLevel;
27
27
  * `undefined` (thinking off) and already-low levels. */
28
28
  declare function clampThinkingForPlanMode(level: ThinkingLevel | undefined): ThinkingLevel | undefined;
29
29
 
30
- /**
31
- * Local model discovery — Ollama, LM Studio, llama.cpp (`llama-server`), vLLM,
32
- * and any other OpenAI-compatible server the user points us at.
33
- *
34
- * Everything rides the OpenAI-compatible `/v1` transport (see the `local`
35
- * provider in gg-ai's stream.ts); the only per-server difference is where the
36
- * *capabilities* come from, because `GET /v1/models` reports nothing useful:
37
- *
38
- * - Ollama → `/api/show` + `/api/ps` → capabilities + running context
39
- * - LM Studio → `/api/v1/models` (v0 fallback) → capabilities + loaded context
40
- * - llama.cpp → `GET /props` → `default_generation_settings.n_ctx`
41
- * - vLLM/other → nothing; `max_model_len` sometimes rides the model object.
42
- *
43
- * Probing never throws: an unreachable server is a normal state (the user just
44
- * doesn't have it running), not an error to surface.
45
- */
46
-
47
30
  /** Which capability API a local endpoint speaks, beyond plain `/v1/models`. */
48
31
  type LocalEndpointKind = "ollama" | "lmstudio" | "llamacpp" | "vllm" | "custom";
49
32
  interface LocalEndpoint {
@@ -91,7 +74,7 @@ declare const DEFAULT_LOCAL_ENDPOINTS: readonly LocalEndpoint[];
91
74
  * auto-compaction already sailed past, while under-guessing only compacts early.
92
75
  */
93
76
  declare const FALLBACK_CONTEXT_WINDOW = 4096;
94
- /** Placeholder token for endpoints with no key — these servers ignore it. */
77
+ /** Token stored for endpoints with no key; never sent on the wire. */
95
78
  declare const LOCAL_API_KEY_PLACEHOLDER = "local";
96
79
  /**
97
80
  * `local/<endpointId>/<rawModelId>`. The raw id can itself contain slashes
@@ -102,6 +85,11 @@ declare function parseLocalModelId(id: string): {
102
85
  endpointId: string;
103
86
  rawId: string;
104
87
  } | undefined;
88
+ /**
89
+ * The model's own name, for a UI that shows the endpoint separately: the last
90
+ * segment of the raw id, so `minimax/minimax-m2:free` reads `minimax-m2:free`.
91
+ */
92
+ declare function localModelShortName(rawId: string): string;
105
93
  declare function isLocalModelId(id: string): boolean;
106
94
  /** Auth-storage key holding the credential (and baseUrl) for one local endpoint. */
107
95
  declare function localAuthStorageKey(endpointId: string): string;
@@ -117,6 +105,17 @@ interface ProbeOptions {
117
105
  * error toast.
118
106
  */
119
107
  declare function probeEndpoint(endpoint: LocalEndpoint, { timeoutMs, signal }?: ProbeOptions): Promise<LocalEndpointProbe>;
108
+ /**
109
+ * The context Ollama serves `rawId` with, read from `/api/ps`. With `load`, first
110
+ * loads the model the way a chat request would (default options), since an
111
+ * unloaded model's size is only decided at load time: the OpenAI endpoint
112
+ * ignores `num_ctx`, so this is the window the agent will really get.
113
+ */
114
+ declare function ollamaServedContext(endpoint: LocalEndpoint, rawId: string, { load, timeoutMs, signal, }?: {
115
+ load?: boolean;
116
+ timeoutMs?: number;
117
+ signal?: AbortSignal;
118
+ }): Promise<number | undefined>;
120
119
  /** Convert a probed local model into the registry shape the whole app speaks. */
121
120
  declare function toModelInfo(model: LocalModel, endpoint: LocalEndpoint): ModelInfo;
122
121
  interface DiscoveryResult {
@@ -305,7 +304,12 @@ declare class AuthStorage {
305
304
  private snapshotIno;
306
305
  /** Per-provider lock to serialize concurrent refresh calls. */
307
306
  private refreshLocks;
308
- constructor(filePath?: string);
307
+ private readonly detectMiniMaxRegion;
308
+ private readonly detectXiaomiCluster;
309
+ constructor(filePath?: string, options?: {
310
+ detectMiniMaxBaseUrl?: (apiKey: string) => Promise<string | undefined>;
311
+ detectXiaomiTokenPlanBaseUrl?: (apiKey: string) => Promise<string | undefined>;
312
+ });
309
313
  /** Path to the on-disk auth file. Useful for status output. */
310
314
  get path(): string;
311
315
  /** List provider keys with stored credentials. */
@@ -380,7 +384,22 @@ declare class AuthStorage {
380
384
  private mutateLatest;
381
385
  private reloadLatest;
382
386
  getCredentials(provider: string): Promise<OAuthCredentials | undefined>;
387
+ /**
388
+ * A MiniMax key saved without an endpoint (every key, until its first use)
389
+ * gets the endpoint of the region that issued it, saved so the check runs
390
+ * once. Without this a Mainland China key went to the Global API, got a 401,
391
+ * and was deleted as invalid.
392
+ */
393
+ private withMiniMaxRegion;
383
394
  setCredentials(provider: string, creds: OAuthCredentials): Promise<void>;
395
+ /**
396
+ * After a 401, move a regional key to the cluster that issued it instead of
397
+ * treating it as invalid. Only the Xiaomi Token Plan is regional: every key
398
+ * used to go to Singapore, so Europe and China keys were rejected and deleted.
399
+ * Returns the new base URL, or undefined when no other cluster accepts the key.
400
+ */
401
+ relocateRegionalApiKey(storageKeys: string[]): Promise<string | undefined>;
402
+ clearRejectedApiKey(storageKey: string): Promise<boolean>;
384
403
  clearCredentials(provider: string): Promise<void>;
385
404
  /**
386
405
  * Mark the credential stored under `storageKey` as usage-exhausted until
@@ -430,6 +449,41 @@ declare class NotLoggedInError extends Error {
430
449
  constructor(provider: string);
431
450
  }
432
451
 
452
+ /**
453
+ * MiniMax runs two separate platforms, and a key only works on the one that
454
+ * issued it: Global (platform.minimax.io) or Mainland China
455
+ * (platform.minimaxi.com). The user's location doesn't matter. Sending a key to
456
+ * the other region's API is rejected as an invalid key.
457
+ */
458
+ declare const MINIMAX_GLOBAL_BASE_URL = "https://api.minimax.io/anthropic";
459
+ declare const MINIMAX_CN_BASE_URL = "https://api.minimax.cn/anthropic";
460
+ /**
461
+ * The Anthropic-compatible base URL for the region that issued `apiKey`, found
462
+ * by asking both regions about the key. Undefined when neither region gives a
463
+ * clear answer (offline, timeouts) — callers then keep the Global default and
464
+ * may ask again later.
465
+ */
466
+ declare function detectMiniMaxBaseUrl(apiKey: string, options?: {
467
+ fetch?: typeof fetch;
468
+ timeoutMs?: number;
469
+ }): Promise<string | undefined>;
470
+
471
+ /**
472
+ * Xiaomi MiMo Token Plan runs separate clusters, and a `tp-` key only works on
473
+ * the cluster that issued it (shown on the user's Token Plan page). Any other
474
+ * cluster answers 401 "Invalid API Key". Pay-as-you-go (API Credits) keys use
475
+ * the single global host and are unaffected.
476
+ */
477
+ 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"];
478
+ /**
479
+ * The Token Plan base URL whose cluster accepts `apiKey`, found by listing
480
+ * models (free, auth-only) on every cluster. Undefined when none accepts it.
481
+ */
482
+ declare function detectXiaomiTokenPlanBaseUrl(apiKey: string, options?: {
483
+ fetch?: typeof fetch;
484
+ timeoutMs?: number;
485
+ }): Promise<string | undefined>;
486
+
433
487
  type AuthMethod = "oauth" | "apikey";
434
488
  /**
435
489
  * One API-key option for a provider that splits auth across multiple distinct
@@ -836,4 +890,4 @@ interface AutoUpdater {
836
890
  }
837
891
  declare function createAutoUpdater(config: AutoUpdateConfig): AutoUpdater;
838
892
 
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, log, loginAnthropic, loginGemini, loginKimi, loginOpenAI, loginXai, oauthStorageKey, openLog, parseLocalModelId, probeEndpoint, providerStorageKeys, readStoredBaseUrlSync, refreshAnthropicToken, refreshGeminiToken, refreshKimiToken, refreshOpenAIToken, refreshXaiToken, registerLogCleanup, resample, setProgressCallback, toModelInfo, transcribeVoice, withFileLock };
893
+ 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, 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, 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, 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,
@@ -61,7 +66,7 @@ import {
61
66
  usesOpenAICodexTransport,
62
67
  withFileLock,
63
68
  withoutPaidTier
64
- } from "./chunk-5ZYOOESD.js";
69
+ } from "./chunk-M53JVW2V.js";
65
70
  import {
66
71
  getAppPaths
67
72
  } from "./chunk-2X5L6U4Z.js";
@@ -94,6 +99,13 @@ var ANTHROPIC_ADAPTIVE_THINKING_LEVELS = [
94
99
  ];
95
100
  var MOONSHOT_K3_THINKING_LEVELS = ["low", "high", "max"];
96
101
  var GLM_THINKING_LEVELS = ["low", "medium", "high", "xhigh", "max"];
102
+ var MINIMAX_EFFORT_THINKING_LEVELS = [
103
+ "low",
104
+ "medium",
105
+ "high",
106
+ "xhigh",
107
+ "max"
108
+ ];
97
109
  var LOCAL_THINKING_LEVELS = ["low", "medium", "high", "max"];
98
110
  function isOpenAIGptModel(provider, model) {
99
111
  return provider === "openai" && model.startsWith("gpt-");
@@ -110,6 +122,9 @@ function isMoonshotK3Model(provider, model) {
110
122
  function isGlmModel(provider) {
111
123
  return provider === "glm";
112
124
  }
125
+ function isMiniMaxEffortModel(provider, model) {
126
+ return provider === "minimax" && model.startsWith("MiniMax-M3.1");
127
+ }
113
128
  function isAnthropicXhighModel(provider, model) {
114
129
  return provider === "anthropic" && /opus-5|opus-4-8|opus-4-7|sonnet-5[-.]5|haiku-5[-.]5/.test(model);
115
130
  }
@@ -142,6 +157,7 @@ function getSupportedThinkingLevels(provider, model) {
142
157
  }
143
158
  if (isMoonshotK3Model(provider, model)) return MOONSHOT_K3_THINKING_LEVELS;
144
159
  if (provider === "deepseek") return DEEPSEEK_THINKING_LEVELS;
160
+ if (isMiniMaxEffortModel(provider, model)) return MINIMAX_EFFORT_THINKING_LEVELS;
145
161
  if (isGlmModel(provider)) {
146
162
  const maxIndex2 = GLM_THINKING_LEVELS.indexOf(maxLevel);
147
163
  if (maxIndex2 === -1) return GLM_THINKING_LEVELS;
@@ -162,7 +178,7 @@ function isThinkingLevelSupported(provider, model, level) {
162
178
  }
163
179
  function getNextThinkingLevel(provider, model, current) {
164
180
  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
181
+ 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
182
  // low/medium/high on `reasoning_effort` (verified against 0.32) and the
167
183
  // other OpenAI-compatible servers use the same three. A model that can't
168
184
  // reason at all already has no supported levels, so it never gets here.
@@ -190,11 +206,12 @@ function clampThinkingForPlanMode(level) {
190
206
  }
191
207
 
192
208
  // src/local-models.ts
209
+ import { LOCAL_NO_API_KEY, localBearerKey } from "@kenkaiiii/gg-ai";
193
210
  var DEFAULT_LOCAL_ENDPOINTS = [
194
211
  { id: "ollama", label: "Ollama", baseUrl: "http://127.0.0.1:11434/v1", kind: "ollama" }
195
212
  ];
196
213
  var FALLBACK_CONTEXT_WINDOW = 4096;
197
- var LOCAL_API_KEY_PLACEHOLDER = "local";
214
+ var LOCAL_API_KEY_PLACEHOLDER = LOCAL_NO_API_KEY;
198
215
  var DEFAULT_PROBE_TIMEOUT_MS = 1200;
199
216
  var ENRICH_CONCURRENCY = 6;
200
217
  var CACHE_TTL_MS = 3e4;
@@ -210,6 +227,9 @@ function parseLocalModelId(id) {
210
227
  if (slash <= 0 || slash === rest.length - 1) return void 0;
211
228
  return { endpointId: rest.slice(0, slash), rawId: rest.slice(slash + 1) };
212
229
  }
230
+ function localModelShortName(rawId) {
231
+ return rawId.slice(rawId.lastIndexOf("/") + 1) || rawId;
232
+ }
213
233
  function isLocalModelId(id) {
214
234
  return parseLocalModelId(id) !== void 0;
215
235
  }
@@ -220,8 +240,9 @@ function endpointRoot(baseUrl) {
220
240
  return baseUrl.replace(/\/+$/, "").replace(/\/v1$/, "");
221
241
  }
222
242
  function authHeaders(endpoint) {
243
+ const key = localBearerKey(endpoint.apiKey);
223
244
  return {
224
- Authorization: `Bearer ${endpoint.apiKey ?? LOCAL_API_KEY_PLACEHOLDER}`,
245
+ ...key ? { Authorization: `Bearer ${key}` } : {},
225
246
  Accept: "application/json"
226
247
  };
227
248
  }
@@ -283,10 +304,22 @@ async function enrich(endpoint, entries, options) {
283
304
  if (endpoint.kind === "lmstudio") return enrichLmStudio(endpoint, entries, options);
284
305
  if (endpoint.kind === "ollama") return enrichOllama(endpoint, entries, options);
285
306
  if (endpoint.kind === "llamacpp") return enrichLlamaCpp(endpoint, entries, options);
307
+ if (endpoint.kind === "custom") return enrichCustom(endpoint, entries, options);
286
308
  return entries.map((entry) => genericModel(endpoint, entry));
287
309
  }
310
+ async function enrichCustom(endpoint, entries, options) {
311
+ const generic = entries.map((entry) => genericModel(endpoint, entry));
312
+ if (generic.every((model) => model.contextWindowKnown)) return generic;
313
+ const root = endpointRoot(endpoint.baseUrl);
314
+ const props = await fetchJson(`${root}/props`, endpoint, options);
315
+ const nCtx = contextLength(props?.default_generation_settings?.n_ctx);
316
+ if (nCtx !== void 0) return llamaCppModels(endpoint, entries, nCtx);
317
+ const lmStudio = await fetchJson(`${root}/api/v1/models`, endpoint, options);
318
+ if (Array.isArray(lmStudio?.models)) return enrichLmStudio(endpoint, entries, options, lmStudio);
319
+ return generic;
320
+ }
288
321
  function genericModel(endpoint, entry) {
289
- const declared = contextLength(entry.max_model_len);
322
+ const declared = contextLength(entry.max_model_len) ?? contextLength(entry.context_length);
290
323
  return {
291
324
  rawId: entry.id,
292
325
  endpointId: endpoint.id,
@@ -313,9 +346,7 @@ async function enrichOllama(endpoint, entries, options) {
313
346
  });
314
347
  const caps = Array.isArray(show?.capabilities) ? show.capabilities : [];
315
348
  if (caps.includes("embedding") && !caps.includes("completion")) return void 0;
316
- const ctx = contextLength(
317
- runningModels.find((model) => model?.name === entry.id || model?.model === entry.id)?.context_length
318
- );
349
+ const ctx = runningContext(runningModels, entry.id) ?? modelfileNumCtx(show?.parameters);
319
350
  return {
320
351
  rawId: entry.id,
321
352
  endpointId: endpoint.id,
@@ -330,12 +361,41 @@ async function enrichOllama(endpoint, entries, options) {
330
361
  });
331
362
  return enriched.filter((model) => model !== void 0);
332
363
  }
364
+ function runningContext(models, rawId) {
365
+ return contextLength(
366
+ models.find((model) => model?.name === rawId || model?.model === rawId)?.context_length
367
+ );
368
+ }
369
+ function modelfileNumCtx(parameters) {
370
+ const match = /^num_ctx\s+(\d+)\s*$/m.exec(parameters ?? "");
371
+ return match ? contextLength(Number(match[1])) : void 0;
372
+ }
373
+ async function ollamaServedContext(endpoint, rawId, {
374
+ load = false,
375
+ timeoutMs = 12e4,
376
+ signal
377
+ } = {}) {
378
+ const root = endpointRoot(endpoint.baseUrl);
379
+ if (load) {
380
+ await fetchJson(`${root}/api/generate`, endpoint, {
381
+ timeoutMs,
382
+ signal,
383
+ method: "POST",
384
+ body: { model: rawId }
385
+ });
386
+ }
387
+ const running = await fetchJson(`${root}/api/ps`, endpoint, {
388
+ timeoutMs: DEFAULT_PROBE_TIMEOUT_MS,
389
+ signal
390
+ });
391
+ return runningContext(Array.isArray(running?.models) ? running.models : [], rawId);
392
+ }
333
393
  function contextLength(value) {
334
394
  return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : void 0;
335
395
  }
336
- async function enrichLmStudio(endpoint, entries, options) {
396
+ async function enrichLmStudio(endpoint, entries, options, fetched) {
337
397
  const root = endpointRoot(endpoint.baseUrl);
338
- const detail = await fetchJson(`${root}/api/v1/models`, endpoint, options);
398
+ const detail = fetched ?? await fetchJson(`${root}/api/v1/models`, endpoint, options);
339
399
  const byId = /* @__PURE__ */ new Map();
340
400
  if (Array.isArray(detail?.models)) {
341
401
  for (const model of detail.models) {
@@ -393,12 +453,17 @@ async function enrichLlamaCpp(endpoint, entries, options) {
393
453
  endpoint,
394
454
  options
395
455
  );
396
- const nCtx = contextLength(props?.default_generation_settings?.n_ctx);
397
- const known = nCtx !== void 0;
456
+ return llamaCppModels(
457
+ endpoint,
458
+ entries,
459
+ contextLength(props?.default_generation_settings?.n_ctx)
460
+ );
461
+ }
462
+ function llamaCppModels(endpoint, entries, nCtx) {
398
463
  return entries.map((entry) => ({
399
464
  ...genericModel(endpoint, entry),
400
- contextWindow: known ? nCtx : FALLBACK_CONTEXT_WINDOW,
401
- contextWindowKnown: known
465
+ contextWindow: nCtx ?? FALLBACK_CONTEXT_WINDOW,
466
+ contextWindowKnown: nCtx !== void 0
402
467
  }));
403
468
  }
404
469
  async function mapLimited(items, limit, fn) {
@@ -555,7 +620,7 @@ var ALL_AUTH_PROVIDERS = [
555
620
  {
556
621
  value: "minimax",
557
622
  label: "MiniMax",
558
- description: "MiniMax M3",
623
+ description: "MiniMax M3.1 Flash, M3",
559
624
  methods: ["apikey"],
560
625
  apiKeyLabel: "MiniMax"
561
626
  },
@@ -1387,6 +1452,8 @@ export {
1387
1452
  HIDDEN_PROVIDERS,
1388
1453
  LOCAL_API_KEY_PLACEHOLDER,
1389
1454
  LOCAL_AUTH_KEY_PREFIX,
1455
+ MINIMAX_CN_BASE_URL,
1456
+ MINIMAX_GLOBAL_BASE_URL,
1390
1457
  MODELS,
1391
1458
  MOONSHOT_OAUTH_KEY,
1392
1459
  NotLoggedInError,
@@ -1395,6 +1462,7 @@ export {
1395
1462
  TelegramBot,
1396
1463
  XAI_OAUTH_KEY,
1397
1464
  XIAOMI_CREDITS_KEY,
1465
+ XIAOMI_TOKEN_PLAN_BASE_URLS,
1398
1466
  authPriorityNote,
1399
1467
  clampThinkingForPlanMode,
1400
1468
  clearLocalDiscoveryCache,
@@ -1403,6 +1471,8 @@ export {
1403
1471
  createAutoUpdater,
1404
1472
  decodeOggOpus,
1405
1473
  describeAuthMethods,
1474
+ detectMiniMaxBaseUrl,
1475
+ detectXiaomiTokenPlanBaseUrl,
1406
1476
  discoverLocalModels,
1407
1477
  downmixToMono,
1408
1478
  dualAuthProvider,
@@ -1446,6 +1516,7 @@ export {
1446
1516
  kimiCodeBaseUrl,
1447
1517
  kimiCodingHeaders,
1448
1518
  localAuthStorageKey,
1519
+ localModelShortName,
1449
1520
  log,
1450
1521
  loginAnthropic,
1451
1522
  loginGemini,
@@ -1453,6 +1524,7 @@ export {
1453
1524
  loginOpenAI,
1454
1525
  loginXai,
1455
1526
  oauthStorageKey,
1527
+ ollamaServedContext,
1456
1528
  openLog,
1457
1529
  parseLocalModelId,
1458
1530
  pendingClaudeCodeVersionRefresh,