@oh-my-pi/pi-catalog 17.2.4 → 17.2.5

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,13 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [17.2.5] - 2026-08-03
6
+
7
+ ### Fixed
8
+
9
+ - Fixed an issue where newly advertised chat models were dropped during dynamic discovery for the `alibaba-token-plan` provider.
10
+ - Fixed a `400` error when forcing a specific tool with DeepSeek reasoning models on OpenCode Zen/Go gateways by automatically downgrading the tool selection mode to `auto` while keeping the tool advertised.
11
+
5
12
  ## [17.2.4] - 2026-08-01
6
13
 
7
14
  ### Added
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-catalog",
4
- "version": "17.2.4",
4
+ "version": "17.2.5",
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",
@@ -35,12 +35,12 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@bufbuild/protobuf": "^2.12.1",
38
- "@oh-my-pi/pi-utils": "17.2.4",
38
+ "@oh-my-pi/pi-utils": "17.2.5",
39
39
  "arktype": "2.2.3",
40
40
  "zod": "^4"
41
41
  },
42
42
  "devDependencies": {
43
- "@oh-my-pi/pi-ai": "17.2.4",
43
+ "@oh-my-pi/pi-ai": "17.2.5",
44
44
  "@types/bun": "^1.3.14"
45
45
  },
46
46
  "engines": {
@@ -318,7 +318,8 @@ export function buildOpenAICompat(spec: ModelSpec<"openai-completions">): Resolv
318
318
  isDeepseekModelIdOrName(spec.name ?? "") ||
319
319
  isOpenCodeDeepseekAlias;
320
320
  const isDirectDeepseekApi = modelMatchesHost(hostModel, "deepseekDirect");
321
- const isDirectDeepseekReasoning = isDirectDeepseekApi && isDeepseekFamily && Boolean(spec.reasoning);
321
+ const isDeepseekReasoning = isDeepseekFamily && Boolean(spec.reasoning);
322
+ const isDirectDeepseekReasoning = isDirectDeepseekApi && isDeepseekReasoning;
322
323
  const isGrok = modelMatchesHost(hostModel, "xai");
323
324
  const isMistral = modelMatchesHost(hostModel, "mistral");
324
325
  const isOpenCodeHost = modelMatchesHost(hostModel, "opencode");
@@ -490,7 +491,12 @@ export function buildOpenAICompat(spec: ModelSpec<"openai-completions">): Resolv
490
491
  disableReasoningOnForcedToolChoice: (isKimiModel && !isMoonshotKimiK3) || isAnthropicModel,
491
492
  disableReasoningOnToolChoice: isDeepseekFamily && Boolean(spec.reasoning) && !isOpenRouter,
492
493
  supportsToolChoice: !isDirectDeepseekReasoning,
493
- supportsForcedToolChoice: !requiresEnabledThinking,
494
+ // DeepSeek reasoning models on OpenCode Zen/Go 400 with
495
+ // "Thinking mode does not support this tool_choice" when a specific
496
+ // function is forced while the gateway's default thinking mode is active.
497
+ // Downgrade only on those gateways: other hosts can turn thinking off via
498
+ // disableReasoningOnToolChoice and must retain hard tool selection.
499
+ supportsForcedToolChoice: !requiresEnabledThinking && !(isOpenCodeHost && isDeepseekReasoning),
494
500
  supportsNamedToolChoice: STRING_ONLY_NAMED_TOOL_CHOICE_PROVIDERS[provider] !== true,
495
501
  maxTokensField: useMaxTokens ? "max_tokens" : "max_completion_tokens",
496
502
  requiresToolResultName: isMistral,
@@ -2833,6 +2833,22 @@ export const ALIBABA_TOKEN_PLAN_STATIC_MODELS: readonly ModelSpec<"openai-comple
2833
2833
  },
2834
2834
  ];
2835
2835
 
2836
+ const ALIBABA_TOKEN_PLAN_NON_CHAT_MODEL_PREFIXES = [
2837
+ "fun-asr",
2838
+ "happyhorse-",
2839
+ "qwen-audio-",
2840
+ "qwen-image-",
2841
+ "text-embedding-",
2842
+ "wan2.7-",
2843
+ ] as const;
2844
+
2845
+ function isAlibabaTokenPlanChatModelId(id: string): boolean {
2846
+ const normalized = id.trim().toLowerCase();
2847
+ return (
2848
+ normalized.length > 0 && !ALIBABA_TOKEN_PLAN_NON_CHAT_MODEL_PREFIXES.some(prefix => normalized.startsWith(prefix))
2849
+ );
2850
+ }
2851
+
2836
2852
  export interface AlibabaTokenPlanModelManagerConfig {
2837
2853
  apiKey?: string;
2838
2854
  baseUrl?: string;
@@ -2859,8 +2875,7 @@ export function alibabaTokenPlanModelManagerOptions(
2859
2875
  provider: "alibaba-token-plan",
2860
2876
  baseUrl,
2861
2877
  apiKey,
2862
- filterModel: (_entry, model) =>
2863
- ALIBABA_TOKEN_PLAN_STATIC_MODELS.some(reference => reference.id === model.id),
2878
+ filterModel: (_entry, model) => isAlibabaTokenPlanChatModelId(model.id),
2864
2879
  mapModel: (_entry, defaults) => {
2865
2880
  const reference = ALIBABA_TOKEN_PLAN_STATIC_MODELS.find(model => model.id === defaults.id);
2866
2881
  return reference