@kenkaiiii/gg-core 5.89.0 → 5.90.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 {
@@ -381,6 +380,7 @@ declare class AuthStorage {
381
380
  private reloadLatest;
382
381
  getCredentials(provider: string): Promise<OAuthCredentials | undefined>;
383
382
  setCredentials(provider: string, creds: OAuthCredentials): Promise<void>;
383
+ clearRejectedApiKey(storageKey: string): Promise<boolean>;
384
384
  clearCredentials(provider: string): Promise<void>;
385
385
  /**
386
386
  * Mark the credential stored under `storageKey` as usage-exhausted until
@@ -836,4 +836,4 @@ interface AutoUpdater {
836
836
  }
837
837
  declare function createAutoUpdater(config: AutoUpdateConfig): AutoUpdater;
838
838
 
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 };
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 };
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 {
@@ -381,6 +380,7 @@ declare class AuthStorage {
381
380
  private reloadLatest;
382
381
  getCredentials(provider: string): Promise<OAuthCredentials | undefined>;
383
382
  setCredentials(provider: string, creds: OAuthCredentials): Promise<void>;
383
+ clearRejectedApiKey(storageKey: string): Promise<boolean>;
384
384
  clearCredentials(provider: string): Promise<void>;
385
385
  /**
386
386
  * Mark the credential stored under `storageKey` as usage-exhausted until
@@ -836,4 +836,4 @@ interface AutoUpdater {
836
836
  }
837
837
  declare function createAutoUpdater(config: AutoUpdateConfig): AutoUpdater;
838
838
 
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 };
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 };
package/dist/index.js CHANGED
@@ -61,7 +61,7 @@ import {
61
61
  usesOpenAICodexTransport,
62
62
  withFileLock,
63
63
  withoutPaidTier
64
- } from "./chunk-5ZYOOESD.js";
64
+ } from "./chunk-QL5357JB.js";
65
65
  import {
66
66
  getAppPaths
67
67
  } from "./chunk-2X5L6U4Z.js";
@@ -190,11 +190,12 @@ function clampThinkingForPlanMode(level) {
190
190
  }
191
191
 
192
192
  // src/local-models.ts
193
+ import { LOCAL_NO_API_KEY, localBearerKey } from "@kenkaiiii/gg-ai";
193
194
  var DEFAULT_LOCAL_ENDPOINTS = [
194
195
  { id: "ollama", label: "Ollama", baseUrl: "http://127.0.0.1:11434/v1", kind: "ollama" }
195
196
  ];
196
197
  var FALLBACK_CONTEXT_WINDOW = 4096;
197
- var LOCAL_API_KEY_PLACEHOLDER = "local";
198
+ var LOCAL_API_KEY_PLACEHOLDER = LOCAL_NO_API_KEY;
198
199
  var DEFAULT_PROBE_TIMEOUT_MS = 1200;
199
200
  var ENRICH_CONCURRENCY = 6;
200
201
  var CACHE_TTL_MS = 3e4;
@@ -210,6 +211,9 @@ function parseLocalModelId(id) {
210
211
  if (slash <= 0 || slash === rest.length - 1) return void 0;
211
212
  return { endpointId: rest.slice(0, slash), rawId: rest.slice(slash + 1) };
212
213
  }
214
+ function localModelShortName(rawId) {
215
+ return rawId.slice(rawId.lastIndexOf("/") + 1) || rawId;
216
+ }
213
217
  function isLocalModelId(id) {
214
218
  return parseLocalModelId(id) !== void 0;
215
219
  }
@@ -220,8 +224,9 @@ function endpointRoot(baseUrl) {
220
224
  return baseUrl.replace(/\/+$/, "").replace(/\/v1$/, "");
221
225
  }
222
226
  function authHeaders(endpoint) {
227
+ const key = localBearerKey(endpoint.apiKey);
223
228
  return {
224
- Authorization: `Bearer ${endpoint.apiKey ?? LOCAL_API_KEY_PLACEHOLDER}`,
229
+ ...key ? { Authorization: `Bearer ${key}` } : {},
225
230
  Accept: "application/json"
226
231
  };
227
232
  }
@@ -283,10 +288,22 @@ async function enrich(endpoint, entries, options) {
283
288
  if (endpoint.kind === "lmstudio") return enrichLmStudio(endpoint, entries, options);
284
289
  if (endpoint.kind === "ollama") return enrichOllama(endpoint, entries, options);
285
290
  if (endpoint.kind === "llamacpp") return enrichLlamaCpp(endpoint, entries, options);
291
+ if (endpoint.kind === "custom") return enrichCustom(endpoint, entries, options);
286
292
  return entries.map((entry) => genericModel(endpoint, entry));
287
293
  }
294
+ async function enrichCustom(endpoint, entries, options) {
295
+ const generic = entries.map((entry) => genericModel(endpoint, entry));
296
+ if (generic.every((model) => model.contextWindowKnown)) return generic;
297
+ const root = endpointRoot(endpoint.baseUrl);
298
+ const props = await fetchJson(`${root}/props`, endpoint, options);
299
+ const nCtx = contextLength(props?.default_generation_settings?.n_ctx);
300
+ if (nCtx !== void 0) return llamaCppModels(endpoint, entries, nCtx);
301
+ const lmStudio = await fetchJson(`${root}/api/v1/models`, endpoint, options);
302
+ if (Array.isArray(lmStudio?.models)) return enrichLmStudio(endpoint, entries, options, lmStudio);
303
+ return generic;
304
+ }
288
305
  function genericModel(endpoint, entry) {
289
- const declared = contextLength(entry.max_model_len);
306
+ const declared = contextLength(entry.max_model_len) ?? contextLength(entry.context_length);
290
307
  return {
291
308
  rawId: entry.id,
292
309
  endpointId: endpoint.id,
@@ -313,9 +330,7 @@ async function enrichOllama(endpoint, entries, options) {
313
330
  });
314
331
  const caps = Array.isArray(show?.capabilities) ? show.capabilities : [];
315
332
  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
- );
333
+ const ctx = runningContext(runningModels, entry.id) ?? modelfileNumCtx(show?.parameters);
319
334
  return {
320
335
  rawId: entry.id,
321
336
  endpointId: endpoint.id,
@@ -330,12 +345,41 @@ async function enrichOllama(endpoint, entries, options) {
330
345
  });
331
346
  return enriched.filter((model) => model !== void 0);
332
347
  }
348
+ function runningContext(models, rawId) {
349
+ return contextLength(
350
+ models.find((model) => model?.name === rawId || model?.model === rawId)?.context_length
351
+ );
352
+ }
353
+ function modelfileNumCtx(parameters) {
354
+ const match = /^num_ctx\s+(\d+)\s*$/m.exec(parameters ?? "");
355
+ return match ? contextLength(Number(match[1])) : void 0;
356
+ }
357
+ async function ollamaServedContext(endpoint, rawId, {
358
+ load = false,
359
+ timeoutMs = 12e4,
360
+ signal
361
+ } = {}) {
362
+ const root = endpointRoot(endpoint.baseUrl);
363
+ if (load) {
364
+ await fetchJson(`${root}/api/generate`, endpoint, {
365
+ timeoutMs,
366
+ signal,
367
+ method: "POST",
368
+ body: { model: rawId }
369
+ });
370
+ }
371
+ const running = await fetchJson(`${root}/api/ps`, endpoint, {
372
+ timeoutMs: DEFAULT_PROBE_TIMEOUT_MS,
373
+ signal
374
+ });
375
+ return runningContext(Array.isArray(running?.models) ? running.models : [], rawId);
376
+ }
333
377
  function contextLength(value) {
334
378
  return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : void 0;
335
379
  }
336
- async function enrichLmStudio(endpoint, entries, options) {
380
+ async function enrichLmStudio(endpoint, entries, options, fetched) {
337
381
  const root = endpointRoot(endpoint.baseUrl);
338
- const detail = await fetchJson(`${root}/api/v1/models`, endpoint, options);
382
+ const detail = fetched ?? await fetchJson(`${root}/api/v1/models`, endpoint, options);
339
383
  const byId = /* @__PURE__ */ new Map();
340
384
  if (Array.isArray(detail?.models)) {
341
385
  for (const model of detail.models) {
@@ -393,12 +437,17 @@ async function enrichLlamaCpp(endpoint, entries, options) {
393
437
  endpoint,
394
438
  options
395
439
  );
396
- const nCtx = contextLength(props?.default_generation_settings?.n_ctx);
397
- const known = nCtx !== void 0;
440
+ return llamaCppModels(
441
+ endpoint,
442
+ entries,
443
+ contextLength(props?.default_generation_settings?.n_ctx)
444
+ );
445
+ }
446
+ function llamaCppModels(endpoint, entries, nCtx) {
398
447
  return entries.map((entry) => ({
399
448
  ...genericModel(endpoint, entry),
400
- contextWindow: known ? nCtx : FALLBACK_CONTEXT_WINDOW,
401
- contextWindowKnown: known
449
+ contextWindow: nCtx ?? FALLBACK_CONTEXT_WINDOW,
450
+ contextWindowKnown: nCtx !== void 0
402
451
  }));
403
452
  }
404
453
  async function mapLimited(items, limit, fn) {
@@ -1446,6 +1495,7 @@ export {
1446
1495
  kimiCodeBaseUrl,
1447
1496
  kimiCodingHeaders,
1448
1497
  localAuthStorageKey,
1498
+ localModelShortName,
1449
1499
  log,
1450
1500
  loginAnthropic,
1451
1501
  loginGemini,
@@ -1453,6 +1503,7 @@ export {
1453
1503
  loginOpenAI,
1454
1504
  loginXai,
1455
1505
  oauthStorageKey,
1506
+ ollamaServedContext,
1456
1507
  openLog,
1457
1508
  parseLocalModelId,
1458
1509
  pendingClaudeCodeVersionRefresh,