@oh-my-pi/pi-catalog 16.3.8 → 16.3.10

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/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [16.3.10] - 2026-07-06
6
+
7
+ ### Fixed
8
+
9
+ - Fixed LiteLLM rich discovery to ignore unusable sentinel placeholders and continue to `/v2/model/info` for real models. ([#4655](https://github.com/can1357/oh-my-pi/issues/4655))
10
+
11
+ ## [16.3.9] - 2026-07-06
12
+
13
+ ### Fixed
14
+
15
+ - Fixed compatibility with OpenCode Go DeepSeek V4 models by sending max_tokens instead of max_completion_tokens to match the provider's API requirements.
16
+
5
17
  ## [16.3.7] - 2026-07-05
6
18
 
7
19
  ### Fixed
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-catalog",
4
- "version": "16.3.8",
4
+ "version": "16.3.10",
5
5
  "description": "Model catalog for omp: bundled model database, provider discovery descriptors, model identity, classification, and equivalence",
6
6
  "homepage": "https://omp.sh",
7
7
  "author": "Can Boluk",
@@ -34,12 +34,12 @@
34
34
  },
35
35
  "dependencies": {
36
36
  "@bufbuild/protobuf": "^2.12.0",
37
- "@oh-my-pi/pi-utils": "16.3.8",
37
+ "@oh-my-pi/pi-utils": "16.3.10",
38
38
  "arktype": "^2.2.0",
39
39
  "zod": "^4"
40
40
  },
41
41
  "devDependencies": {
42
- "@oh-my-pi/pi-ai": "16.3.8",
42
+ "@oh-my-pi/pi-ai": "16.3.10",
43
43
  "@types/bun": "^1.3.14"
44
44
  },
45
45
  "engines": {
package/src/models.json CHANGED
@@ -60395,6 +60395,7 @@
60395
60395
  "maxTokens": 384000,
60396
60396
  "compat": {
60397
60397
  "supportsToolChoice": false,
60398
+ "maxTokensField": "max_tokens",
60398
60399
  "reasoningContentField": "reasoning_content",
60399
60400
  "requiresReasoningContentForToolCalls": true
60400
60401
  },
@@ -60436,6 +60437,7 @@
60436
60437
  "maxTokens": 384000,
60437
60438
  "compat": {
60438
60439
  "supportsToolChoice": false,
60440
+ "maxTokensField": "max_tokens",
60439
60441
  "reasoningContentField": "reasoning_content",
60440
60442
  "requiresReasoningContentForToolCalls": true
60441
60443
  },
@@ -71921,9 +71923,9 @@
71921
71923
  "text"
71922
71924
  ],
71923
71925
  "cost": {
71924
- "input": 0.5740000000000001,
71925
- "output": 1.804,
71926
- "cacheRead": 0.1066,
71926
+ "input": 0.56,
71927
+ "output": 1.76,
71928
+ "cacheRead": 0.10400000000000001,
71927
71929
  "cacheWrite": 0
71928
71930
  },
71929
71931
  "contextWindow": 1048576,
@@ -72143,7 +72145,7 @@
72143
72145
  "synthetic": {
72144
72146
  "hf:MiniMaxAI/MiniMax-M3": {
72145
72147
  "id": "hf:MiniMaxAI/MiniMax-M3",
72146
- "name": "MiniMaxAI/MiniMax-M3",
72148
+ "name": "MiniMax-M3",
72147
72149
  "api": "openai-completions",
72148
72150
  "provider": "synthetic",
72149
72151
  "baseUrl": "https://api.synthetic.new/openai/v1",
@@ -72158,7 +72160,7 @@
72158
72160
  "cacheRead": 0.6,
72159
72161
  "cacheWrite": 0
72160
72162
  },
72161
- "contextWindow": 262144,
72163
+ "contextWindow": 524288,
72162
72164
  "maxTokens": 65536,
72163
72165
  "thinking": {
72164
72166
  "mode": "effort",
@@ -72173,7 +72175,7 @@
72173
72175
  },
72174
72176
  "hf:moonshotai/Kimi-K2.7-Code": {
72175
72177
  "id": "hf:moonshotai/Kimi-K2.7-Code",
72176
- "name": "moonshotai/Kimi-K2.7-Code",
72178
+ "name": "Kimi K2.7 Code",
72177
72179
  "api": "openai-completions",
72178
72180
  "provider": "synthetic",
72179
72181
  "baseUrl": "https://api.synthetic.new/openai/v1",
@@ -72203,7 +72205,7 @@
72203
72205
  },
72204
72206
  "hf:nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-NVFP4": {
72205
72207
  "id": "hf:nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-NVFP4",
72206
- "name": "nvidia/NVIDIA-Nemotron-3-Super-120B-A12B-NVFP4",
72208
+ "name": "Nemotron 3 Super 120B A12B",
72207
72209
  "api": "openai-completions",
72208
72210
  "provider": "synthetic",
72209
72211
  "baseUrl": "https://api.synthetic.new/openai/v1",
@@ -72232,7 +72234,7 @@
72232
72234
  },
72233
72235
  "hf:openai/gpt-oss-120b": {
72234
72236
  "id": "hf:openai/gpt-oss-120b",
72235
- "name": "openai/gpt-oss-120b",
72237
+ "name": "GPT OSS 120B",
72236
72238
  "api": "openai-completions",
72237
72239
  "provider": "synthetic",
72238
72240
  "baseUrl": "https://api.synthetic.new/openai/v1",
@@ -72259,7 +72261,7 @@
72259
72261
  },
72260
72262
  "hf:Qwen/Qwen3.6-27B": {
72261
72263
  "id": "hf:Qwen/Qwen3.6-27B",
72262
- "name": "Qwen/Qwen3.6-27B",
72264
+ "name": "Qwen3.6 27B",
72263
72265
  "api": "openai-completions",
72264
72266
  "provider": "synthetic",
72265
72267
  "baseUrl": "https://api.synthetic.new/openai/v1",
@@ -72288,7 +72290,7 @@
72288
72290
  },
72289
72291
  "hf:zai-org/GLM-4.7-Flash": {
72290
72292
  "id": "hf:zai-org/GLM-4.7-Flash",
72291
- "name": "zai-org/GLM-4.7-Flash",
72293
+ "name": "GLM-4.7-Flash",
72292
72294
  "api": "openai-completions",
72293
72295
  "provider": "synthetic",
72294
72296
  "baseUrl": "https://api.synthetic.new/openai/v1",
@@ -72317,7 +72319,7 @@
72317
72319
  },
72318
72320
  "hf:zai-org/GLM-5.2": {
72319
72321
  "id": "hf:zai-org/GLM-5.2",
72320
- "name": "zai-org/GLM-5.2",
72322
+ "name": "GLM-5.2",
72321
72323
  "api": "openai-completions",
72322
72324
  "provider": "synthetic",
72323
72325
  "baseUrl": "https://api.synthetic.new/openai/v1",
@@ -83217,6 +83219,14 @@
83217
83219
  },
83218
83220
  "contextWindow": 2000000,
83219
83221
  "maxTokens": 2000000,
83222
+ "compat": {
83223
+ "reasoningEffortMap": {
83224
+ "minimal": "low"
83225
+ },
83226
+ "includeEncryptedReasoning": false,
83227
+ "filterReasoningHistory": true,
83228
+ "omitReasoningEffort": false
83229
+ },
83220
83230
  "thinking": {
83221
83231
  "mode": "effort",
83222
83232
  "efforts": [
@@ -83229,14 +83239,6 @@
83229
83239
  "effortMap": {
83230
83240
  "minimal": "low"
83231
83241
  }
83232
- },
83233
- "compat": {
83234
- "reasoningEffortMap": {
83235
- "minimal": "low"
83236
- },
83237
- "includeEncryptedReasoning": false,
83238
- "filterReasoningHistory": true,
83239
- "omitReasoningEffort": false
83240
83242
  }
83241
83243
  },
83242
83244
  "grok-4.3": {
@@ -83258,6 +83260,14 @@
83258
83260
  },
83259
83261
  "contextWindow": 1000000,
83260
83262
  "maxTokens": 1000000,
83263
+ "compat": {
83264
+ "reasoningEffortMap": {
83265
+ "minimal": "low"
83266
+ },
83267
+ "includeEncryptedReasoning": false,
83268
+ "filterReasoningHistory": true,
83269
+ "omitReasoningEffort": false
83270
+ },
83261
83271
  "thinking": {
83262
83272
  "mode": "effort",
83263
83273
  "efforts": [
@@ -83270,14 +83280,6 @@
83270
83280
  "effortMap": {
83271
83281
  "minimal": "low"
83272
83282
  }
83273
- },
83274
- "compat": {
83275
- "reasoningEffortMap": {
83276
- "minimal": "low"
83277
- },
83278
- "includeEncryptedReasoning": false,
83279
- "filterReasoningHistory": true,
83280
- "omitReasoningEffort": false
83281
83283
  }
83282
83284
  },
83283
83285
  "grok-build": {
@@ -3037,6 +3037,11 @@ const LITELLM_RICH_ENDPOINTS = ["/model_group/info", "/v2/model/info", "/model/i
3037
3037
  export const OPENAI_COMPAT_DISCOVERY_DEFAULT_CONTEXT_WINDOW = 128_000;
3038
3038
  export const OPENAI_COMPAT_DISCOVERY_DEFAULT_MAX_TOKENS = 32_768;
3039
3039
  const UNKNOWN_PROXY_COST = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 } as const;
3040
+ const LITELLM_UNUSABLE_SENTINEL_IDS: Record<string, true> = {
3041
+ "all-team-models": true,
3042
+ "all-proxy-models": true,
3043
+ "no-default-models": true,
3044
+ };
3040
3045
 
3041
3046
  export function normalizeLiteLLMManagementBaseUrl(baseUrl: string): string {
3042
3047
  const trimmed = baseUrl.trim().replace(/\/+$/g, "");
@@ -3142,11 +3147,59 @@ function getSupportedOpenAIParams(entry: LiteLLMRichModelEntry): string[] | unde
3142
3147
  return value.flatMap(item => (typeof item === "string" ? [item] : []));
3143
3148
  }
3144
3149
 
3150
+ function isLiteLLMUnusableSentinelPlaceholder(entry: LiteLLMRichModelEntry): boolean {
3151
+ const modelGroup = toNonEmptyString(entry.model_group);
3152
+ const id = toNonEmptyString(entry.id);
3153
+ if (
3154
+ (modelGroup === undefined || LITELLM_UNUSABLE_SENTINEL_IDS[modelGroup] !== true) &&
3155
+ (id === undefined || LITELLM_UNUSABLE_SENTINEL_IDS[id] !== true)
3156
+ ) {
3157
+ return false;
3158
+ }
3159
+ const providers = entry.providers;
3160
+ if (providers !== undefined && (!Array.isArray(providers) || providers.length > 0)) {
3161
+ return false;
3162
+ }
3163
+ const modelName = toNonEmptyString(entry.model_name);
3164
+ if (modelName && LITELLM_UNUSABLE_SENTINEL_IDS[modelName] !== true) {
3165
+ return false;
3166
+ }
3167
+ if (id && LITELLM_UNUSABLE_SENTINEL_IDS[id] !== true) {
3168
+ return false;
3169
+ }
3170
+ const backendModel = toNonEmptyString(getLiteLLMParams(entry)?.model);
3171
+ if (backendModel && LITELLM_UNUSABLE_SENTINEL_IDS[backendModel] !== true) {
3172
+ return false;
3173
+ }
3174
+ if (
3175
+ toPositiveNumber(getLiteLLMMetadataValue(entry, "max_input_tokens"), null) !== null ||
3176
+ toPositiveNumber(getLiteLLMMetadataValue(entry, "max_output_tokens"), null) !== null
3177
+ ) {
3178
+ return false;
3179
+ }
3180
+ if (
3181
+ getLiteLLMMetadataValue(entry, "supports_vision") === true ||
3182
+ getLiteLLMMetadataValue(entry, "supports_reasoning") === true ||
3183
+ getLiteLLMMetadataValue(entry, "supports_function_calling") === true ||
3184
+ getLiteLLMMetadataValue(entry, "supports_tools") === true
3185
+ ) {
3186
+ return false;
3187
+ }
3188
+ const supportedOpenAIParams = getSupportedOpenAIParams(entry);
3189
+ if (supportedOpenAIParams && supportedOpenAIParams.length > 0) {
3190
+ return false;
3191
+ }
3192
+ return true;
3193
+ }
3194
+
3145
3195
  function mapLiteLLMRichEntry<TApi extends Api>(
3146
3196
  entry: LiteLLMRichModelEntry,
3147
3197
  options: FetchLiteLLMRichModelsOptions<TApi>,
3148
3198
  runtimeBaseUrl: string,
3149
3199
  ): ModelSpec<TApi> | null {
3200
+ if (isLiteLLMUnusableSentinelPlaceholder(entry)) {
3201
+ return null;
3202
+ }
3150
3203
  const id = getLiteLLMRichModelId(entry);
3151
3204
  if (!id) {
3152
3205
  return null;
@@ -3286,11 +3339,11 @@ export function litellmModelManagerOptions(
3286
3339
  const baseUrl = config?.baseUrl ?? Bun.env.LITELLM_BASE_URL ?? "http://localhost:4000/v1";
3287
3340
  return {
3288
3341
  providerId: "litellm",
3289
- // rich-v2 invalidates rows cached before reseller usage-suffix stripping
3290
- // (stale display names like `MiniMax-M3 (3x usage)`); bump the version
3291
- // whenever the mappers below change, or warm authoritative caches keep
3292
- // serving pre-change rows for the full TTL.
3293
- cacheProviderId: `litellm:rich-v2:${Bun.hash(baseUrl).toString(36)}`,
3342
+ // rich-v3 invalidates rows cached before reseller usage-suffix stripping
3343
+ // and placeholder-only `all-team-models` filtering; bump the version whenever
3344
+ // the mappers below change, or warm authoritative caches keep serving
3345
+ // pre-change rows for the full TTL.
3346
+ cacheProviderId: `litellm:rich-v3:${Bun.hash(baseUrl).toString(36)}`,
3294
3347
  // litellm is a local-only proxy and is never bundled in models.json (that
3295
3348
  // would leak the machine's localhost catalog). Prefer the proxy's richer
3296
3349
  // management metadata, then fall back to /v1/models and enrich bare ids