@hilbras/omnicode 1.2.2 → 1.2.3

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/main.mjs +298 -277
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @hilbras/omnicode
2
2
 
3
+ ## 1.2.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [`b9e3bbd`](https://github.com/Hilbras/OmniCode/commit/b9e3bbd570cde32e613db2f0e6997c52279e7698) Thanks [@lacrous](https://github.com/lacrous)! - Show each model's real context window from its provider catalog instead of a flat default; a model with no declared window now says so until you set one with /context.
8
+
9
+ - Requests to providers that reject the prompt_cache_key field now retry without it instead of failing.
10
+
3
11
  ## 1.2.2
4
12
 
5
13
  ### Patch Changes
package/dist/main.mjs CHANGED
@@ -55760,12 +55760,19 @@ function userExtras(existing, remoteOwnedFields) {
55760
55760
  }
55761
55761
  return out;
55762
55762
  }
55763
+ function preservedMaxContextSize(current, remote) {
55764
+ if (remote.maxContextSize !== void 0) return void 0;
55765
+ const existing = current["maxContextSize"];
55766
+ return typeof existing === "number" && Number.isFinite(existing) && existing > 0 ? existing : void 0;
55767
+ }
55763
55768
  function mergeRefreshedModelAlias(existing, remote, remoteOwnedFields) {
55764
55769
  const current = isRecord$25(existing) ? existing : {};
55765
55770
  const overrides = cloneOverrides(isRecord$25(current["overrides"]) ? current["overrides"] : void 0);
55771
+ const carried = preservedMaxContextSize(current, remote);
55766
55772
  return {
55767
55773
  ...userExtras(current, remoteOwnedFields),
55768
55774
  ...remote,
55775
+ maxContextSize: remote.maxContextSize ?? carried,
55769
55776
  ...overrides !== void 0 ? { overrides } : {}
55770
55777
  };
55771
55778
  }
@@ -57170,7 +57177,6 @@ function resolveMaxContextSize(model) {
57170
57177
  const output = model.limit?.output;
57171
57178
  if (typeof context === "number" && Number.isInteger(context) && context > 0) return context;
57172
57179
  if (typeof output === "number" && Number.isInteger(output) && output > 0) return output;
57173
- return CUSTOM_REGISTRY_DEFAULT_MAX_CONTEXT;
57174
57180
  }
57175
57181
  function resolveCapabilities(model) {
57176
57182
  if (hasRichCapabilityHints(model)) return capabilitiesFromCustomEntry(model);
@@ -57349,7 +57355,7 @@ function applyCustomRegistryEntries(config, entries, source, removal) {
57349
57355
  config["defaultProvider"] = r.previousDefaultProvider !== void 0 && config.providers[r.previousDefaultProvider] !== void 0 ? r.previousDefaultProvider : void 0;
57350
57356
  if (r.previousDefault !== void 0 && config.defaultModel === void 0) config.thinking = void 0;
57351
57357
  }
57352
- var CUSTOM_REGISTRY_DEFAULT_MAX_CONTEXT, CUSTOM_REGISTRY_DEFAULT_CAPABILITIES, ALLOWED_PROVIDER_TYPES, RESERVED_PROVIDER_IDS, CustomRegistryApiError;
57358
+ var CUSTOM_REGISTRY_DEFAULT_CAPABILITIES, ALLOWED_PROVIDER_TYPES, RESERVED_PROVIDER_IDS, CustomRegistryApiError;
57353
57359
  var init_custom_registry = __esmMin((() => {
57354
57360
  init_api_error();
57355
57361
  init_managed_omnicode();
@@ -57357,7 +57363,6 @@ var init_custom_registry = __esmMin((() => {
57357
57363
  init_open_platform();
57358
57364
  init_provider_credential();
57359
57365
  init_utils$4();
57360
- CUSTOM_REGISTRY_DEFAULT_MAX_CONTEXT = 131072;
57361
57366
  CUSTOM_REGISTRY_DEFAULT_CAPABILITIES = ["tool_use"];
57362
57367
  ALLOWED_PROVIDER_TYPES = new Set([
57363
57368
  "anthropic",
@@ -57481,7 +57486,7 @@ function toDiscoveredModel(row) {
57481
57486
  const rawId = row["id"] ?? row["name"];
57482
57487
  if (typeof rawId !== "string" || rawId.trim().length === 0) return void 0;
57483
57488
  const id = stripResourcePrefix(rawId.trim());
57484
- const maxContextSize = positiveInt$1(row["context_length"] ?? row["context_window"]) ?? positiveInt$1(row["max_output_tokens"]) ?? positiveInt$1(row["max_context_size"]);
57489
+ const maxContextSize = positiveInt$1(row["context_length"] ?? row["context_window"]) ?? positiveInt$1(row["max_context_size"]);
57485
57490
  const rawName = row["name"] ?? row["display_name"];
57486
57491
  const capabilities = [];
57487
57492
  const object = row["object"];
@@ -57595,7 +57600,7 @@ function applyDiscoveredModels(config, providerId, models, aliasPrefix = `${prov
57595
57600
  const alias = {
57596
57601
  provider: providerId,
57597
57602
  model: model.id,
57598
- maxContextSize: model.maxContextSize ?? 131072,
57603
+ maxContextSize: model.maxContextSize,
57599
57604
  capabilities: [...model.capabilities ?? CUSTOM_REGISTRY_DEFAULT_CAPABILITIES],
57600
57605
  displayName: model.displayName ?? model.id
57601
57606
  };
@@ -62933,7 +62938,7 @@ var init_schema$4 = __esmMin((() => {
62933
62938
  ModelAliasBaseSchema = object({
62934
62939
  provider: string(),
62935
62940
  model: string(),
62936
- maxContextSize: number$1().int().min(1),
62941
+ maxContextSize: number$1().int().min(1).optional(),
62937
62942
  maxInputSize: number$1().int().min(1).optional(),
62938
62943
  maxOutputSize: number$1().int().min(1).optional(),
62939
62944
  capabilities: array(string()).optional(),
@@ -64194,7 +64199,7 @@ function applyEnvModelConfig(config, env = process.env) {
64194
64199
  const apiKey = trimmed$2(env["OMNICODE_MODEL_API_KEY"]);
64195
64200
  if (apiKey === void 0) fail$1("OMNICODE_MODEL_NAME is set but OMNICODE_MODEL_API_KEY is missing.");
64196
64201
  const maxContextRaw = trimmed$2(env["OMNICODE_MODEL_MAX_CONTEXT_SIZE"]);
64197
- const maxContextSize = maxContextRaw === void 0 ? DEFAULT_MAX_CONTEXT_SIZE$1 : parsePositiveInt$4(maxContextRaw, "OMNICODE_MODEL_MAX_CONTEXT_SIZE");
64202
+ const maxContextSize = maxContextRaw === void 0 ? DEFAULT_MAX_CONTEXT_SIZE : parsePositiveInt$4(maxContextRaw, "OMNICODE_MODEL_MAX_CONTEXT_SIZE");
64198
64203
  const type = parseProviderType(trimmed$2(env["OMNICODE_MODEL_PROVIDER_TYPE"]));
64199
64204
  const baseUrl = trimmed$2(env["OMNICODE_MODEL_BASE_URL"]) ?? DEFAULT_BASE_URL$2[type];
64200
64205
  const provider = {
@@ -64265,7 +64270,7 @@ function rawThinking(config) {
64265
64270
  const raw = config.raw?.["thinking"];
64266
64271
  return typeof raw === "object" && raw !== null && !Array.isArray(raw) ? raw : void 0;
64267
64272
  }
64268
- var ENV_MODEL_PROVIDER_KEY$1, ENV_MODEL_ALIAS_KEY$1, ALLOWED_TYPES, DEFAULT_BASE_URL$2, DEFAULT_MAX_CONTEXT_SIZE$1, DEFAULT_CAPABILITIES$1;
64273
+ var ENV_MODEL_PROVIDER_KEY$1, ENV_MODEL_ALIAS_KEY$1, ALLOWED_TYPES, DEFAULT_BASE_URL$2, DEFAULT_MAX_CONTEXT_SIZE, DEFAULT_CAPABILITIES$1;
64269
64274
  var init_env_model = __esmMin((() => {
64270
64275
  init_errors$46();
64271
64276
  init_resolve$1();
@@ -64281,7 +64286,7 @@ var init_env_model = __esmMin((() => {
64281
64286
  omnicode: "https://api.hilbras.ai/v1",
64282
64287
  openai: "https://api.openai.com/v1"
64283
64288
  };
64284
- DEFAULT_MAX_CONTEXT_SIZE$1 = 262144;
64289
+ DEFAULT_MAX_CONTEXT_SIZE = 262144;
64285
64290
  DEFAULT_CAPABILITIES$1 = ["image_in", "thinking"];
64286
64291
  }));
64287
64292
  //#endregion
@@ -64830,7 +64835,7 @@ function effectiveModelAlias(alias, providerType) {
64830
64835
  ...overrides
64831
64836
  };
64832
64837
  if (overrides?.supportEfforts !== void 0 && overrides.defaultEffort === void 0 && effective.defaultEffort !== void 0 && !overrides.supportEfforts.includes(effective.defaultEffort)) delete effective.defaultEffort;
64833
- return withAnthropicProfile$1(effective.maxInputSize !== void 0 && effective.maxInputSize > effective.maxContextSize ? {
64838
+ return withAnthropicProfile$1(effective.maxInputSize !== void 0 && effective.maxContextSize !== void 0 && effective.maxInputSize > effective.maxContextSize ? {
64834
64839
  ...effective,
64835
64840
  maxInputSize: effective.maxContextSize
64836
64841
  } : effective, providerType);
@@ -186227,20 +186232,6 @@ function parseAnthropicModelVersion(model, requireClaudeMarker = false) {
186227
186232
  };
186228
186233
  return null;
186229
186234
  }
186230
- function lookupClaudeCeiling(version) {
186231
- const { family, major, minor } = version;
186232
- if (minor !== null) for (let candidate = minor; candidate >= 0; candidate--) {
186233
- const ceiling = CEILING_BY_FAMILY_VERSION[`${family}-${major}-${candidate}`];
186234
- if (ceiling !== void 0) return ceiling;
186235
- }
186236
- return CEILING_BY_FAMILY_VERSION[`${family}-${major}`];
186237
- }
186238
- function resolveDefaultMaxTokens(model, override) {
186239
- const parsed = parseAnthropicModelVersion(model, true);
186240
- const ceiling = parsed === null ? void 0 : lookupClaudeCeiling(parsed);
186241
- if (ceiling === void 0) return override ?? FALLBACK_MAX_TOKENS;
186242
- return override === void 0 ? ceiling : Math.min(override, ceiling);
186243
- }
186244
186235
  function matchKnownAnthropicModelProfile(model) {
186245
186236
  const normalized = model.toLowerCase();
186246
186237
  if (/mythos[-._]preview/.test(normalized)) return ALWAYS_ADAPTIVE_MAX_PROFILE;
@@ -186334,7 +186325,7 @@ function encodeThinking(thinking, model) {
186334
186325
  if ((profile.supportsEffortParam || budgetTokens === void 0) && effort !== "on") patch["output_config"] = { effort };
186335
186326
  return patch;
186336
186327
  }
186337
- var INTERLEAVED_THINKING_BETA, BUDGET_THINKING_EFFORTS, ADAPTIVE_MAX_EFFORTS, LATEST_OPUS_THINKING_EFFORTS, BUDGET_PROFILE, OPUS_45_PROFILE, ADAPTIVE_MAX_PROFILE, LATEST_OPUS_PROFILE, ALWAYS_ADAPTIVE_PROFILE, ALWAYS_ADAPTIVE_MAX_PROFILE, FAMILY_FIRST_RE, VERSION_FIRST_RE, BARE_FAMILY_RE, CEILING_BY_FAMILY_VERSION, FALLBACK_MAX_TOKENS, CLAUDE_FAMILY_WORD_RE;
186328
+ var INTERLEAVED_THINKING_BETA, BUDGET_THINKING_EFFORTS, ADAPTIVE_MAX_EFFORTS, LATEST_OPUS_THINKING_EFFORTS, BUDGET_PROFILE, OPUS_45_PROFILE, ADAPTIVE_MAX_PROFILE, LATEST_OPUS_PROFILE, ALWAYS_ADAPTIVE_PROFILE, ALWAYS_ADAPTIVE_MAX_PROFILE, FAMILY_FIRST_RE, VERSION_FIRST_RE, BARE_FAMILY_RE, CLAUDE_FAMILY_WORD_RE;
186338
186329
  var init_profile$1 = __esmMin((() => {
186339
186330
  init_thinking$2();
186340
186331
  INTERLEAVED_THINKING_BETA = "interleaved-thinking-2025-05-14";
@@ -186389,32 +186380,6 @@ var init_profile$1 = __esmMin((() => {
186389
186380
  FAMILY_FIRST_RE = /(opus|sonnet|haiku|fable|mythos)[-._](\d{1,2})(?!\d)(?:[-._](\d{1,2})(?!\d))?/;
186390
186381
  VERSION_FIRST_RE = /(\d{1,2})[-._](\d{1,2})[-._](opus|sonnet|haiku)/;
186391
186382
  BARE_FAMILY_RE = /(\d{1,2})[-._](opus|sonnet|haiku)/;
186392
- CEILING_BY_FAMILY_VERSION = {
186393
- "fable-5": 128e3,
186394
- "mythos-5": 128e3,
186395
- "opus-4-8": 128e3,
186396
- "opus-4-7": 128e3,
186397
- "opus-4-6": 128e3,
186398
- "opus-4-5": 64e3,
186399
- "opus-4-1": 32e3,
186400
- "opus-4-0": 32e3,
186401
- "opus-4": 32e3,
186402
- "sonnet-5": 128e3,
186403
- "sonnet-4-6": 128e3,
186404
- "sonnet-4-5": 64e3,
186405
- "sonnet-4-0": 64e3,
186406
- "sonnet-4": 64e3,
186407
- "haiku-4-5": 64e3,
186408
- "haiku-4": 64e3,
186409
- "opus-3-5": 8192,
186410
- "sonnet-3-5": 8192,
186411
- "sonnet-3-7": 8192,
186412
- "haiku-3-5": 8192,
186413
- "opus-3": 4096,
186414
- "sonnet-3": 4096,
186415
- "haiku-3": 4096
186416
- };
186417
- FALLBACK_MAX_TOKENS = 64e3;
186418
186383
  CLAUDE_FAMILY_WORD_RE = /\b(?:opus|sonnet|haiku|fable|mythos)\b/;
186419
186384
  }));
186420
186385
  //#endregion
@@ -186521,7 +186486,7 @@ function assembleAnthropicRequest(input, parts) {
186521
186486
  return {
186522
186487
  params: {
186523
186488
  model: input.model.model,
186524
- max_tokens: resolveDefaultMaxTokens(input.model.model, input.model.defaultMaxTokens),
186489
+ max_tokens: input.model.defaultMaxTokens,
186525
186490
  metadata: input.cacheKey === void 0 ? void 0 : { user_id: input.cacheKey },
186526
186491
  ...restKwargs,
186527
186492
  system: input.systemPrompt ? [{
@@ -186730,13 +186695,10 @@ function prepareAnthropicRequest(input, options) {
186730
186695
  if (input.thinking !== void 0) kwargs = applyThinking(kwargs, input.thinking, trait?.thinking, ctx, (t, c) => encodeThinking(t, c.model)).kwargs;
186731
186696
  if (input.responseFormat !== void 0) kwargs = applyAnthropicResponseFormat(kwargs, input.responseFormat);
186732
186697
  const cap = resolveMaxCompletionCap(input);
186733
- if (cap !== void 0) {
186734
- const capped = resolveDefaultMaxTokens(ctx.model.model, cap);
186735
- kwargs = {
186736
- ...kwargs,
186737
- ...trait?.encodeMaxCompletionTokens?.(capped, ctx) ?? encodeAnthropicMaxTokens(capped)
186738
- };
186739
- }
186698
+ if (cap !== void 0) kwargs = {
186699
+ ...kwargs,
186700
+ ...trait?.encodeMaxCompletionTokens?.(cap, ctx) ?? encodeAnthropicMaxTokens(cap)
186701
+ };
186740
186702
  kwargs = assign$1(kwargs, input.extraParams?.anthropic ?? {});
186741
186703
  if (input.thinking?.keep !== void 0) kwargs = applyAnthropicThinkingKeep(kwargs, input.thinking.keep);
186742
186704
  kwargs = shake(kwargs);
@@ -188283,7 +188245,9 @@ var init_prompt_cache_key_fallback = __esmMin((() => {
188283
188245
  /unsupported parameter/,
188284
188246
  /unknown parameter/,
188285
188247
  /unrecognized request argument/,
188286
- /extra inputs are not permitted/
188248
+ /extra inputs are not permitted/,
188249
+ /is unsupported/,
188250
+ /is not supported/
188287
188251
  ];
188288
188252
  PromptCacheKeyRejections = class {
188289
188253
  rejected = /* @__PURE__ */ new Set();
@@ -189523,7 +189487,7 @@ var init_protocolAdapterRegistry = __esmMin((() => {
189523
189487
  provider: route.providerId,
189524
189488
  model: model.name,
189525
189489
  capability: toLlmCapability(model.capabilities),
189526
- maxContextSize: model.maxContextSize > 0 ? model.maxContextSize : void 0,
189490
+ maxContextSize: typeof model.maxContextSize === "number" && model.maxContextSize > 0 ? model.maxContextSize : void 0,
189527
189491
  maxInputSize: model.maxInputSize,
189528
189492
  defaultMaxTokens: model.providerOptions?.defaultMaxTokens,
189529
189493
  baseUrl: model.baseUrl,
@@ -189687,7 +189651,7 @@ function mergeModelOverrides(existing, fromEnv) {
189687
189651
  ...fromEnv
189688
189652
  };
189689
189653
  }
189690
- var ENV_MODEL_ALIAS_KEY, DEFAULT_MAX_CONTEXT_SIZE, DEFAULT_CAPABILITIES, omnicodeModelEnvOverlay;
189654
+ var ENV_MODEL_ALIAS_KEY, DEFAULT_CAPABILITIES, omnicodeModelEnvOverlay;
189691
189655
  var init_envOverlay = __esmMin((() => {
189692
189656
  init_errors$39();
189693
189657
  init_env$1();
@@ -189697,7 +189661,6 @@ var init_envOverlay = __esmMin((() => {
189697
189661
  init_provider_definition();
189698
189662
  init_configSection$17();
189699
189663
  ENV_MODEL_ALIAS_KEY = "__omnicode_env_model__";
189700
- DEFAULT_MAX_CONTEXT_SIZE = 262144;
189701
189664
  DEFAULT_CAPABILITIES = ["image_in", "thinking"];
189702
189665
  omnicodeModelEnvOverlay = {
189703
189666
  apply(effective, getEnv, validate) {
@@ -189721,7 +189684,7 @@ var init_envOverlay = __esmMin((() => {
189721
189684
  return changed;
189722
189685
  }
189723
189686
  const maxContextRaw = trimmed(getEnv("OMNICODE_MODEL_MAX_CONTEXT_SIZE"));
189724
- const maxContextSize = maxContextRaw === void 0 ? DEFAULT_MAX_CONTEXT_SIZE : parsePositiveInt$2(maxContextRaw, "OMNICODE_MODEL_MAX_CONTEXT_SIZE");
189687
+ const maxContextSize = maxContextRaw === void 0 ? void 0 : parsePositiveInt$2(maxContextRaw, "OMNICODE_MODEL_MAX_CONTEXT_SIZE");
189725
189688
  const maxOutputRaw = trimmed(getEnv("OMNICODE_MODEL_MAX_OUTPUT_SIZE"));
189726
189689
  const maxOutputSize = maxOutputRaw === void 0 ? void 0 : parsePositiveInt$2(maxOutputRaw, "OMNICODE_MODEL_MAX_OUTPUT_SIZE");
189727
189690
  const capabilities = parseCapabilities(getEnv("OMNICODE_MODEL_CAPABILITIES")) ?? DEFAULT_CAPABILITIES;
@@ -190173,11 +190136,6 @@ function resolveModelForReady(modelId, models, providers, defaultProvider) {
190173
190136
  resolved: false,
190174
190137
  reason: "unresolvable"
190175
190138
  };
190176
- const maxContextSize = model.maxContextSize;
190177
- if (maxContextSize === void 0 || maxContextSize <= 0) return {
190178
- resolved: false,
190179
- reason: "unresolvable"
190180
- };
190181
190139
  if (resolveModelProtocol(model, provider) === void 0) return {
190182
190140
  resolved: false,
190183
190141
  reason: "unresolvable"
@@ -190217,7 +190175,7 @@ function toProtocolModelFallback(modelId, record, providerType) {
190217
190175
  provider: effective.provider ?? "",
190218
190176
  model: modelId,
190219
190177
  display_name: effective.displayName ?? effective.model ?? modelId,
190220
- max_context_size: effective.maxContextSize ?? 0,
190178
+ max_context_size: effective.maxContextSize,
190221
190179
  capabilities: effective.capabilities,
190222
190180
  support_efforts: effective.supportEfforts,
190223
190181
  default_effort: effective.defaultEffort
@@ -190253,7 +190211,7 @@ var init_catalog$2 = __esmMin((() => {
190253
190211
  provider: string().min(1),
190254
190212
  model: string().min(1),
190255
190213
  display_name: string().min(1).optional(),
190256
- max_context_size: number$1().int().min(1),
190214
+ max_context_size: number$1().int().min(1).optional(),
190257
190215
  capabilities: array(string()).optional(),
190258
190216
  support_efforts: array(string()).optional(),
190259
190217
  default_effort: string().optional()
@@ -191414,7 +191372,7 @@ function resolveModelCapabilities(declaredCapabilities, detected, maxContextSize
191414
191372
  audio_in: declared.has("audio_in") || detected.audio_in,
191415
191373
  thinking: declared.has("thinking") || declared.has("always_thinking") || detected.thinking,
191416
191374
  tool_use: declared.has("tool_use") || detected.tool_use,
191417
- max_context_tokens: maxContextSize,
191375
+ max_context_tokens: maxContextSize ?? 0,
191418
191376
  max_input_tokens: maxInputSize,
191419
191377
  dynamically_loaded_tools: declared.has("dynamically_loaded_tools") || detected.dynamically_loaded_tools === true
191420
191378
  };
@@ -191735,7 +191693,6 @@ var init_catalog_service = __esmMin((() => {
191735
191693
  const providerType = providerConfig?.type ?? protocol;
191736
191694
  const resolvedBaseUrl = protocol === "anthropic" && rawBaseUrl !== void 0 ? stripTrailingV1(rawBaseUrl) : rawBaseUrl;
191737
191695
  if (wireName === void 0) throw new Error2(CONFIG_INVALID_ERROR_CODE, `Model "${id}" must define a wire-facing name in config.toml.`);
191738
- if (model.maxContextSize === void 0) throw new Error2(CONFIG_INVALID_ERROR_CODE, `Model "${id}" must define a positive max_context_size in config.toml.`);
191739
191696
  const detectedCapability = this.protocolRegistry.resolveCapability(protocol, wireName, providerType);
191740
191697
  const capabilities = resolveModelCapabilities(model.capabilities, detectedCapability, model.maxContextSize, model.maxInputSize);
191741
191698
  const providerOptions = buildProtocolProviderOptions(model, protocol, providerConfig, resolvedBaseUrl);
@@ -284072,7 +284029,7 @@ function catalogModelToAlias(providerId, model) {
284072
284029
  return {
284073
284030
  provider: providerId,
284074
284031
  model: model.id,
284075
- maxContextSize: model.capability.max_context_tokens,
284032
+ maxContextSize: model.capability.max_context_tokens > 0 ? model.capability.max_context_tokens : void 0,
284076
284033
  maxInputSize: model.capability.max_input_tokens,
284077
284034
  maxOutputSize: model.maxOutputSize,
284078
284035
  capabilities: model.alwaysThinking === true ? caps?.map((cap) => cap === "thinking" ? "always_thinking" : cap) : caps,
@@ -334266,6 +334223,195 @@ var init_catalog_fetch = __esmMin((() => {
334266
334223
  init_built_in_catalog();
334267
334224
  }));
334268
334225
  //#endregion
334226
+ //#region src/utils/built-in-providers.ts
334227
+ function getBuiltInProvider(id) {
334228
+ const needle = id.trim().toLowerCase();
334229
+ return BUILT_IN_PROVIDERS.find((p) => p.id === needle);
334230
+ }
334231
+ var OPENCODE_FREE_MODEL_PATTERNS, OPENCODE_FREE_TIER, BUILT_IN_PROVIDERS;
334232
+ var init_built_in_providers = __esmMin((() => {
334233
+ OPENCODE_FREE_MODEL_PATTERNS = [
334234
+ "*-free",
334235
+ "*-contributor-free",
334236
+ "big-pickle"
334237
+ ];
334238
+ OPENCODE_FREE_TIER = {
334239
+ baseUrl: "https://opencode.ai/inference/v1",
334240
+ match: OPENCODE_FREE_MODEL_PATTERNS,
334241
+ apiKey: "public"
334242
+ };
334243
+ BUILT_IN_PROVIDERS = [
334244
+ {
334245
+ id: "cline",
334246
+ name: "Cline",
334247
+ wire: "openai",
334248
+ baseUrl: "https://api.cline.bot/api/v1",
334249
+ description: "One key for Anthropic, OpenAI, Google and more",
334250
+ consoleUrl: "https://app.cline.bot"
334251
+ },
334252
+ {
334253
+ id: "openrouter",
334254
+ name: "OpenRouter",
334255
+ wire: "openai",
334256
+ baseUrl: "https://openrouter.ai/api/v1",
334257
+ description: "One key for 400+ models across many providers",
334258
+ consoleUrl: "https://openrouter.ai/keys",
334259
+ catalogProvider: "openrouter"
334260
+ },
334261
+ {
334262
+ id: "opencode-zen",
334263
+ name: "OpenCode Zen",
334264
+ wire: "openai",
334265
+ baseUrl: "https://opencode.ai/zen/v1",
334266
+ description: "Curated models tested by the OpenCode team",
334267
+ consoleUrl: "https://opencode.ai/zen",
334268
+ protocolOverrides: { "claude-*": "anthropic" },
334269
+ excludedModels: OPENCODE_FREE_MODEL_PATTERNS,
334270
+ freeTier: [OPENCODE_FREE_TIER],
334271
+ catalogProvider: "opencode"
334272
+ },
334273
+ {
334274
+ id: "opencode-go",
334275
+ name: "OpenCode Go",
334276
+ wire: "openai",
334277
+ baseUrl: "https://opencode.ai/zen/go/v1",
334278
+ description: "OpenCode Zen models on the Go plan",
334279
+ consoleUrl: "https://opencode.ai/zen",
334280
+ excludedModels: OPENCODE_FREE_MODEL_PATTERNS,
334281
+ freeTier: [OPENCODE_FREE_TIER],
334282
+ catalogProvider: "opencode"
334283
+ },
334284
+ {
334285
+ id: "nvidia",
334286
+ name: "NVIDIA",
334287
+ wire: "openai",
334288
+ baseUrl: "https://integrate.api.nvidia.com/v1",
334289
+ description: "NVIDIA-hosted open models, free developer tier",
334290
+ consoleUrl: "https://build.nvidia.com",
334291
+ keyHint: "nvapi-",
334292
+ catalogProvider: "nvidia"
334293
+ },
334294
+ {
334295
+ id: "nara",
334296
+ name: "NaraRouter",
334297
+ wire: "openai",
334298
+ baseUrl: "https://router.bynara.id/v1",
334299
+ description: "Affordable multi-model gateway",
334300
+ consoleUrl: "https://router.bynara.id",
334301
+ keyHint: "sk-nry-"
334302
+ },
334303
+ {
334304
+ id: "tokenharbor",
334305
+ name: "Token Harbor",
334306
+ wire: "openai",
334307
+ baseUrl: "https://tokenharbor.ai/v1",
334308
+ description: "One universal key for many AI providers",
334309
+ consoleUrl: "https://tokenharbor.ai/dashboard/api-keys",
334310
+ keyHint: "thk_live_"
334311
+ },
334312
+ {
334313
+ id: "openai",
334314
+ name: "OpenAI",
334315
+ wire: "openai",
334316
+ baseUrl: "https://api.openai.com/v1",
334317
+ description: "GPT, o-series and Codex models",
334318
+ consoleUrl: "https://platform.openai.com/api-keys",
334319
+ keyHint: "sk-",
334320
+ catalogProvider: "openai"
334321
+ },
334322
+ {
334323
+ id: "anthropic",
334324
+ name: "Anthropic",
334325
+ wire: "anthropic",
334326
+ baseUrl: "https://api.anthropic.com",
334327
+ description: "Claude models",
334328
+ consoleUrl: "https://console.anthropic.com/settings/keys",
334329
+ keyHint: "sk-ant-",
334330
+ authStyle: "x-api-key",
334331
+ catalogProvider: "anthropic"
334332
+ },
334333
+ {
334334
+ id: "gemini",
334335
+ name: "Google Gemini",
334336
+ wire: "google-genai",
334337
+ baseUrl: "https://generativelanguage.googleapis.com/v1beta",
334338
+ description: "Gemini models",
334339
+ consoleUrl: "https://aistudio.google.com/apikey",
334340
+ keyHint: "AIza",
334341
+ authStyle: "x-goog-api-key",
334342
+ catalogProvider: "google"
334343
+ },
334344
+ {
334345
+ id: "grok",
334346
+ name: "xAI Grok",
334347
+ wire: "openai",
334348
+ baseUrl: "https://api.x.ai/v1",
334349
+ description: "Grok models",
334350
+ consoleUrl: "https://console.x.ai",
334351
+ keyHint: "xai-",
334352
+ catalogProvider: "xai"
334353
+ },
334354
+ {
334355
+ id: "groq",
334356
+ name: "Groq",
334357
+ wire: "openai",
334358
+ baseUrl: "https://api.groq.com/openai/v1",
334359
+ description: "Fast open models on Groq hardware",
334360
+ consoleUrl: "https://console.groq.com/keys",
334361
+ keyHint: "gsk_",
334362
+ catalogProvider: "groq"
334363
+ },
334364
+ {
334365
+ id: "qwen",
334366
+ name: "Qwen",
334367
+ wire: "openai",
334368
+ baseUrl: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
334369
+ description: "Alibaba Qwen models",
334370
+ consoleUrl: "https://bailian.console.alibabacloud.com/",
334371
+ keyHint: "sk-",
334372
+ catalogProvider: "alibaba"
334373
+ },
334374
+ {
334375
+ id: "minimax",
334376
+ name: "MiniMax",
334377
+ wire: "openai",
334378
+ baseUrl: "https://api.minimax.io/v1",
334379
+ description: "MiniMax models",
334380
+ consoleUrl: "https://platform.minimax.io/user-center/basic-information/interface-key",
334381
+ catalogProvider: "minimax"
334382
+ },
334383
+ {
334384
+ id: "deepseek",
334385
+ name: "DeepSeek",
334386
+ wire: "openai",
334387
+ baseUrl: "https://api.deepseek.com",
334388
+ description: "DeepSeek chat and reasoning models",
334389
+ consoleUrl: "https://platform.deepseek.com/api_keys",
334390
+ keyHint: "sk-",
334391
+ catalogProvider: "deepseek"
334392
+ },
334393
+ {
334394
+ id: "mistral",
334395
+ name: "Mistral",
334396
+ wire: "openai",
334397
+ baseUrl: "https://api.mistral.ai/v1",
334398
+ description: "Mistral and Magistral models",
334399
+ consoleUrl: "https://console.mistral.ai/api-keys",
334400
+ catalogProvider: "mistral"
334401
+ },
334402
+ {
334403
+ id: "huggingface",
334404
+ name: "Hugging Face",
334405
+ wire: "openai",
334406
+ baseUrl: "https://router.huggingface.co/v1",
334407
+ description: "Open models via the Hugging Face router",
334408
+ consoleUrl: "https://huggingface.co/settings/tokens",
334409
+ keyHint: "hf_",
334410
+ catalogProvider: "huggingface"
334411
+ }
334412
+ ];
334413
+ }));
334414
+ //#endregion
334269
334415
  //#region src/utils/builtin-model-import.ts
334270
334416
  /**
334271
334417
  * Whether `id` is named by a pattern: `claude-*` is a prefix, `*-free` a suffix,
@@ -334410,7 +334556,8 @@ function backfillCatalogLimits(input) {
334410
334556
  if (id === void 0) continue;
334411
334557
  const limit = input.limits.get(id);
334412
334558
  if (limit === void 0) continue;
334413
- if (record["maxContextSize"] !== 131072) continue;
334559
+ const current = record["maxContextSize"];
334560
+ if (current !== void 0 && current !== 131072) continue;
334414
334561
  input.models[key] = {
334415
334562
  ...record,
334416
334563
  maxContextSize: limit.context
@@ -334420,6 +334567,32 @@ function backfillCatalogLimits(input) {
334420
334567
  return touched;
334421
334568
  }
334422
334569
  /**
334570
+ * Fills real context windows onto every configured built-in provider's aliases.
334571
+ *
334572
+ * Runs after a provider refresh: `/models` answers with ids and no limits, so a
334573
+ * refresh that preserves an alias keeps whatever it already held — including a
334574
+ * flat default written by an older release. Without this pass a config written
334575
+ * before real values were resolved never converges on them, and the user has to
334576
+ * re-add the provider to see a real context window.
334577
+ *
334578
+ * Providers with no `catalogProvider`, and an unreachable catalog, are no-ops.
334579
+ */
334580
+ async function backfillBuiltInContextWindows(input) {
334581
+ let touched = false;
334582
+ for (const providerId of input.providerIds) {
334583
+ const catalogProvider = getBuiltInProvider(providerId)?.catalogProvider;
334584
+ if (catalogProvider === void 0) continue;
334585
+ const limits = await fetchCatalogLimits(catalogProvider, input.fetchImpl ?? fetch);
334586
+ if (limits.size === 0) continue;
334587
+ if (backfillCatalogLimits({
334588
+ models: input.models,
334589
+ providerId,
334590
+ limits
334591
+ })) touched = true;
334592
+ }
334593
+ return touched;
334594
+ }
334595
+ /**
334423
334596
  * Drops free-tier aliases for a provider that the free endpoint no longer
334424
334597
  * offers.
334425
334598
  *
@@ -334445,183 +334618,7 @@ function pruneRetiredFreeTierAliases(input) {
334445
334618
  var init_builtin_model_import = __esmMin((() => {
334446
334619
  init_src$5();
334447
334620
  init_catalog_fetch();
334448
- }));
334449
- //#endregion
334450
- //#region src/utils/built-in-providers.ts
334451
- function getBuiltInProvider(id) {
334452
- const needle = id.trim().toLowerCase();
334453
- return BUILT_IN_PROVIDERS.find((p) => p.id === needle);
334454
- }
334455
- var OPENCODE_FREE_MODEL_PATTERNS, OPENCODE_FREE_TIER, BUILT_IN_PROVIDERS;
334456
- var init_built_in_providers = __esmMin((() => {
334457
- OPENCODE_FREE_MODEL_PATTERNS = [
334458
- "*-free",
334459
- "*-contributor-free",
334460
- "big-pickle"
334461
- ];
334462
- OPENCODE_FREE_TIER = {
334463
- baseUrl: "https://opencode.ai/inference/v1",
334464
- match: OPENCODE_FREE_MODEL_PATTERNS,
334465
- apiKey: "public"
334466
- };
334467
- BUILT_IN_PROVIDERS = [
334468
- {
334469
- id: "cline",
334470
- name: "Cline",
334471
- wire: "openai",
334472
- baseUrl: "https://api.cline.bot/api/v1",
334473
- description: "One key for Anthropic, OpenAI, Google and more",
334474
- consoleUrl: "https://app.cline.bot"
334475
- },
334476
- {
334477
- id: "openrouter",
334478
- name: "OpenRouter",
334479
- wire: "openai",
334480
- baseUrl: "https://openrouter.ai/api/v1",
334481
- description: "One key for 400+ models across many providers",
334482
- consoleUrl: "https://openrouter.ai/keys"
334483
- },
334484
- {
334485
- id: "opencode-zen",
334486
- name: "OpenCode Zen",
334487
- wire: "openai",
334488
- baseUrl: "https://opencode.ai/zen/v1",
334489
- description: "Curated models tested by the OpenCode team",
334490
- consoleUrl: "https://opencode.ai/zen",
334491
- protocolOverrides: { "claude-*": "anthropic" },
334492
- excludedModels: OPENCODE_FREE_MODEL_PATTERNS,
334493
- freeTier: [OPENCODE_FREE_TIER],
334494
- catalogProvider: "opencode"
334495
- },
334496
- {
334497
- id: "opencode-go",
334498
- name: "OpenCode Go",
334499
- wire: "openai",
334500
- baseUrl: "https://opencode.ai/zen/go/v1",
334501
- description: "OpenCode Zen models on the Go plan",
334502
- consoleUrl: "https://opencode.ai/zen",
334503
- excludedModels: OPENCODE_FREE_MODEL_PATTERNS,
334504
- freeTier: [OPENCODE_FREE_TIER],
334505
- catalogProvider: "opencode"
334506
- },
334507
- {
334508
- id: "nvidia",
334509
- name: "NVIDIA",
334510
- wire: "openai",
334511
- baseUrl: "https://integrate.api.nvidia.com/v1",
334512
- description: "NVIDIA-hosted open models, free developer tier",
334513
- consoleUrl: "https://build.nvidia.com",
334514
- keyHint: "nvapi-"
334515
- },
334516
- {
334517
- id: "nara",
334518
- name: "NaraRouter",
334519
- wire: "openai",
334520
- baseUrl: "https://router.bynara.id/v1",
334521
- description: "Affordable multi-model gateway",
334522
- consoleUrl: "https://router.bynara.id",
334523
- keyHint: "sk-nry-"
334524
- },
334525
- {
334526
- id: "tokenharbor",
334527
- name: "Token Harbor",
334528
- wire: "openai",
334529
- baseUrl: "https://tokenharbor.ai/v1",
334530
- description: "One universal key for many AI providers",
334531
- consoleUrl: "https://tokenharbor.ai/dashboard/api-keys",
334532
- keyHint: "thk_live_"
334533
- },
334534
- {
334535
- id: "openai",
334536
- name: "OpenAI",
334537
- wire: "openai",
334538
- baseUrl: "https://api.openai.com/v1",
334539
- description: "GPT, o-series and Codex models",
334540
- consoleUrl: "https://platform.openai.com/api-keys",
334541
- keyHint: "sk-"
334542
- },
334543
- {
334544
- id: "anthropic",
334545
- name: "Anthropic",
334546
- wire: "anthropic",
334547
- baseUrl: "https://api.anthropic.com",
334548
- description: "Claude models",
334549
- consoleUrl: "https://console.anthropic.com/settings/keys",
334550
- keyHint: "sk-ant-",
334551
- authStyle: "x-api-key"
334552
- },
334553
- {
334554
- id: "gemini",
334555
- name: "Google Gemini",
334556
- wire: "google-genai",
334557
- baseUrl: "https://generativelanguage.googleapis.com/v1beta",
334558
- description: "Gemini models",
334559
- consoleUrl: "https://aistudio.google.com/apikey",
334560
- keyHint: "AIza",
334561
- authStyle: "x-goog-api-key"
334562
- },
334563
- {
334564
- id: "grok",
334565
- name: "xAI Grok",
334566
- wire: "openai",
334567
- baseUrl: "https://api.x.ai/v1",
334568
- description: "Grok models",
334569
- consoleUrl: "https://console.x.ai",
334570
- keyHint: "xai-"
334571
- },
334572
- {
334573
- id: "groq",
334574
- name: "Groq",
334575
- wire: "openai",
334576
- baseUrl: "https://api.groq.com/openai/v1",
334577
- description: "Fast open models on Groq hardware",
334578
- consoleUrl: "https://console.groq.com/keys",
334579
- keyHint: "gsk_"
334580
- },
334581
- {
334582
- id: "qwen",
334583
- name: "Qwen",
334584
- wire: "openai",
334585
- baseUrl: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
334586
- description: "Alibaba Qwen models",
334587
- consoleUrl: "https://bailian.console.alibabacloud.com/",
334588
- keyHint: "sk-"
334589
- },
334590
- {
334591
- id: "minimax",
334592
- name: "MiniMax",
334593
- wire: "openai",
334594
- baseUrl: "https://api.minimax.io/v1",
334595
- description: "MiniMax models",
334596
- consoleUrl: "https://platform.minimax.io/user-center/basic-information/interface-key"
334597
- },
334598
- {
334599
- id: "deepseek",
334600
- name: "DeepSeek",
334601
- wire: "openai",
334602
- baseUrl: "https://api.deepseek.com",
334603
- description: "DeepSeek chat and reasoning models",
334604
- consoleUrl: "https://platform.deepseek.com/api_keys",
334605
- keyHint: "sk-"
334606
- },
334607
- {
334608
- id: "mistral",
334609
- name: "Mistral",
334610
- wire: "openai",
334611
- baseUrl: "https://api.mistral.ai/v1",
334612
- description: "Mistral and Magistral models",
334613
- consoleUrl: "https://console.mistral.ai/api-keys"
334614
- },
334615
- {
334616
- id: "huggingface",
334617
- name: "Hugging Face",
334618
- wire: "openai",
334619
- baseUrl: "https://router.huggingface.co/v1",
334620
- description: "Open models via the Hugging Face router",
334621
- consoleUrl: "https://huggingface.co/settings/tokens",
334622
- keyHint: "hf_"
334623
- }
334624
- ];
334621
+ init_built_in_providers();
334625
334622
  }));
334626
334623
  //#endregion
334627
334624
  //#region src/utils/free-tier-sync.ts
@@ -334702,14 +334699,34 @@ async function refreshAllProviderModels(host, options = {}) {
334702
334699
  resolveOAuthToken: (providerName, oauthRef) => host.resolveOAuthToken(providerName, oauthRef),
334703
334700
  userAgent: host.userAgent
334704
334701
  }, options);
334702
+ await backfillContextWindows(host, options.providerId);
334705
334703
  await syncConfiguredFreeTiers({
334706
334704
  getConfig: () => host.getConfig(),
334707
334705
  setConfig: (patch) => host.setConfig(patch)
334708
334706
  }, options.providerId);
334709
334707
  return result;
334710
334708
  }
334709
+ /**
334710
+ * Upgrades aliases that still carry a flat default, or no declared window at
334711
+ * all, to the real context window from the models.dev catalog.
334712
+ *
334713
+ * A refresh merges the endpoint's own fields over each alias, and `/models`
334714
+ * declares no limits — so a value written by an older release survives the
334715
+ * refresh unchanged forever. Only re-running the catalog read converges it,
334716
+ * which is why this rides along with every refresh rather than only at add.
334717
+ */
334718
+ async function backfillContextWindows(host, providerId) {
334719
+ const config = await host.getConfig();
334720
+ const models = { ...config.models };
334721
+ const ids = Object.keys(config.providers ?? {});
334722
+ if (await backfillBuiltInContextWindows({
334723
+ models,
334724
+ providerIds: providerId === void 0 ? ids : ids.filter((id) => id === providerId)
334725
+ })) await host.setConfig({ models });
334726
+ }
334711
334727
  var init_refresh_providers = __esmMin((() => {
334712
334728
  init_src$14();
334729
+ init_builtin_model_import();
334713
334730
  init_free_tier_sync();
334714
334731
  }));
334715
334732
  //#endregion
@@ -408749,15 +408766,15 @@ var init_thinking_config = __esmMin((() => {}));
408749
408766
  //#endregion
408750
408767
  //#region src/utils/usage/usage-format.ts
408751
408768
  /**
408752
- * Format a token count in 1024-based units: context sizes are powers of
408753
- * two, so 262144 reads as "256k", not "262.1k". k values at or above
408754
- * 100 are rounded to whole numbers ("977k").
408769
+ * Format a token count in the 1000-based units vendors declare contexts with,
408770
+ * so a 1,000,000-token window reads "1M" rather than "977k". A value that
408771
+ * rounds up into the next unit is promoted to it, so 999,999 never reads "1000k".
408755
408772
  */
408756
408773
  function formatTokenCount(n) {
408757
408774
  if (!Number.isFinite(n) || n < 0) return "0";
408758
- if (n >= 1024 * 1024) return `${trimDecimal(n / (1024 * 1024))}M`;
408759
- if (n >= 1024) {
408760
- const k = n / 1024;
408775
+ if (n >= 1e3 && Math.round(n / 1e3) >= 1e3) return `${trimDecimal(n / 1e6)}M`;
408776
+ if (n >= 1e3) {
408777
+ const k = n / 1e3;
408761
408778
  return `${k >= 100 ? Math.round(k) : trimDecimal(k)}k`;
408762
408779
  }
408763
408780
  return String(n);
@@ -409639,15 +409656,15 @@ function buildUsageReportLines(options) {
409639
409656
  const value = (text) => currentTheme.fg("text", text);
409640
409657
  const muted = (text) => currentTheme.fg("textDim", text);
409641
409658
  const lines = [accent("Session usage"), ...buildSessionUsageSection(options.sessionUsage, options.sessionUsageError, value, muted)];
409659
+ lines.push("");
409660
+ lines.push(accent("Context window"));
409642
409661
  if (options.maxContextTokens > 0) {
409643
409662
  const ratio = safeUsageRatio(options.contextUsage);
409644
409663
  const bar = renderProgressBar(ratio, 20);
409645
409664
  const pct = `${String(usagePercent(options.contextTokens, options.maxContextTokens))}%`;
409646
409665
  const barColoured = currentTheme.fg(severityColor(ratioSeverity(ratio)), bar);
409647
- lines.push("");
409648
- lines.push(accent("Context window"));
409649
409666
  lines.push(` ${barColoured} ${value(pct.padStart(6, " "))} ` + muted(`(${formatTokenCount(options.contextTokens)} / ${formatTokenCount(options.maxContextTokens)})`));
409650
- }
409667
+ } else lines.push(` ${value(formatTokenCount(options.contextTokens))} used ` + muted("(no context window declared — set one with /context)"));
409651
409668
  const managedSection = buildManagedUsageReportLines({
409652
409669
  managedUsage: options.managedUsage,
409653
409670
  managedUsageError: options.managedUsageError
@@ -409795,7 +409812,7 @@ function buildStatusReportLines(options) {
409795
409812
  const bar = renderProgressBar(safeRatio, 20);
409796
409813
  const barColoured = currentTheme.fg(severityToken(ratioSeverity(safeRatio)), bar);
409797
409814
  lines.push(` ${barColoured} ${value(`${String(usagePercent(tokens, maxTokens))}%`.padStart(6, " "))} ` + muted(`(${formatTokenCount(tokens)} / ${formatTokenCount(maxTokens)})`));
409798
- } else lines.push(` ${muted("No context window data available.")}`);
409815
+ } else lines.push(` ${value(formatTokenCount(tokens))} used ` + muted("(no context window declared — set one with /context)"));
409799
409816
  const managedSection = buildManagedUsageReportLines({
409800
409817
  managedUsage: options.managedUsage,
409801
409818
  managedUsageError: options.managedUsageError
@@ -410717,10 +410734,13 @@ function parseContextSize(raw) {
410717
410734
  if (!Number.isSafeInteger(value) || value < 1) return void 0;
410718
410735
  return value;
410719
410736
  }
410737
+ /**
410738
+ * The same 1000-based reading the footer and `/usage` use, so one window is
410739
+ * written identically wherever it appears — and a value that is not a round
410740
+ * thousand (1,048,576) reads as a unit instead of "1048.576K".
410741
+ */
410720
410742
  function formatContextSize(tokens) {
410721
- if (tokens >= 1e6 && tokens % 1e5 === 0) return `${String(tokens / 1e6)}M tokens`;
410722
- if (tokens >= 1e3) return `${String(tokens / 1e3)}K tokens`;
410723
- return `${String(tokens)} tokens`;
410743
+ return `${formatTokenCount(tokens)} tokens`;
410724
410744
  }
410725
410745
  async function handleContextCommand(host, args) {
410726
410746
  const trimmed = args.trim();
@@ -410823,6 +410843,7 @@ async function applyContextSize(host, alias, raw) {
410823
410843
  var CONTEXT_SIZE_PATTERN, SIZE_MULTIPLIERS;
410824
410844
  var init_context = __esmMin((() => {
410825
410845
  init_src$5();
410846
+ init_usage_format();
410826
410847
  init_api_key_input_dialog();
410827
410848
  init_choice_picker();
410828
410849
  init_model_selector();
@@ -483927,20 +483948,19 @@ async function snapshotFreeTierAliases(host, providerId) {
483927
483948
  * `importBuiltInExtras`, so both add paths leave identical config.
483928
483949
  */
483929
483950
  async function routeFreeTierAliases(host, target) {
483930
- for (const source of target.freeTier ?? []) {
483931
- const limits = target.catalogProvider === void 0 ? /* @__PURE__ */ new Map() : await fetchCatalogLimits(target.catalogProvider);
483932
- let config = await host.harness.getConfig({ reload: true });
483933
- const models = { ...config.models };
483934
- const changed = backfillCatalogLimits({
483951
+ const limits = target.catalogProvider === void 0 ? /* @__PURE__ */ new Map() : await fetchCatalogLimits(target.catalogProvider);
483952
+ if (limits.size > 0) {
483953
+ const models = { ...(await host.harness.getConfig({ reload: true })).models };
483954
+ if (backfillCatalogLimits({
483935
483955
  models,
483936
483956
  providerId: target.providerId,
483937
483957
  limits
483938
- });
483958
+ })) await host.harness.setConfig({ models });
483959
+ }
483960
+ for (const source of target.freeTier ?? []) {
483961
+ let config = await host.harness.getConfig({ reload: true });
483962
+ const models = { ...config.models };
483939
483963
  const { ids, failure } = await fetchFreeTierModelIds(source);
483940
- if (changed) {
483941
- await host.harness.setConfig({ models });
483942
- config = await host.harness.getConfig({ reload: true });
483943
- }
483944
483964
  if (ids.length === 0) {
483945
483965
  host.showError(describeFreeTierFailure(source.baseUrl, failure));
483946
483966
  const preserved = target.previousFreeAliases ?? {};
@@ -498195,7 +498215,7 @@ var AuthFlowController = class {
498195
498215
  availableModels,
498196
498216
  availableProviders,
498197
498217
  model: defaultModel,
498198
- maxContextTokens: selected.maxContextSize
498218
+ maxContextTokens: selected.overrides?.maxContextSize ?? selected.maxContextSize ?? 0
498199
498219
  };
498200
498220
  host.setAppState(appStatePatch);
498201
498221
  return activated;
@@ -514530,7 +514550,8 @@ var OmnicodeTUI = class {
514530
514550
  if (startupModel !== void 0) {
514531
514551
  patch.model = startupModel;
514532
514552
  const selected = config.models?.[startupModel];
514533
- if (selected?.maxContextSize !== void 0) patch.maxContextTokens = selected.maxContextSize;
514553
+ const declaredWindow = selected?.overrides?.maxContextSize ?? selected?.maxContextSize;
514554
+ if (declaredWindow !== void 0) patch.maxContextTokens = declaredWindow;
514534
514555
  } else {
514535
514556
  patch.model = "";
514536
514557
  patch.maxContextTokens = 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hilbras/omnicode",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "The Starting Point for Next-Gen Agents",
5
5
  "license": "MIT",
6
6
  "author": "Hilbras",