@linxiraos/pi-catalog 1.0.4 → 1.0.6

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 (85) hide show
  1. package/CHANGELOG.md +33 -3
  2. package/dist/types/build.d.ts +14 -0
  3. package/dist/types/compat/anthropic.d.ts +18 -0
  4. package/dist/types/compat/apply.d.ts +7 -0
  5. package/dist/types/compat/bedrock.d.ts +3 -0
  6. package/dist/types/compat/devin.d.ts +9 -0
  7. package/dist/types/compat/openai.d.ts +28 -0
  8. package/dist/types/discovery/antigravity.d.ts +70 -0
  9. package/dist/types/discovery/codex.d.ts +36 -0
  10. package/dist/types/discovery/cursor-gen/agent_pb.d.ts +16769 -0
  11. package/dist/types/discovery/cursor.d.ts +23 -0
  12. package/dist/types/discovery/devin-gen/buf/validate/validate_pb.d.ts +1715 -0
  13. package/dist/types/discovery/devin-gen/exa/analytics_pb/analytics_pb.d.ts +693 -0
  14. package/dist/types/discovery/devin-gen/exa/api_server_pb/api_server_pb.d.ts +9158 -0
  15. package/dist/types/discovery/devin-gen/exa/auth_pb/auth_pb.d.ts +52 -0
  16. package/dist/types/discovery/devin-gen/exa/auto_cascade_common_pb/auto_cascade_common_pb.d.ts +276 -0
  17. package/dist/types/discovery/devin-gen/exa/bug_checker_pb/bug_checker_pb.d.ts +78 -0
  18. package/dist/types/discovery/devin-gen/exa/cascade_plugins_pb/cascade_plugins_pb.d.ts +999 -0
  19. package/dist/types/discovery/devin-gen/exa/chat_pb/chat_pb.d.ts +1704 -0
  20. package/dist/types/discovery/devin-gen/exa/code_edit/code_edit_pb/code_edit_pb.d.ts +656 -0
  21. package/dist/types/discovery/devin-gen/exa/codeium_common_pb/codeium_common_pb.d.ts +15014 -0
  22. package/dist/types/discovery/devin-gen/exa/context_module_pb/context_module_pb.d.ts +607 -0
  23. package/dist/types/discovery/devin-gen/exa/cortex_pb/cortex_pb.d.ts +11830 -0
  24. package/dist/types/discovery/devin-gen/exa/diff_action_pb/diff_action_pb.d.ts +248 -0
  25. package/dist/types/discovery/devin-gen/exa/index_pb/index_pb.d.ts +1747 -0
  26. package/dist/types/discovery/devin-gen/exa/knowledge_base_pb/knowledge_base_pb.d.ts +509 -0
  27. package/dist/types/discovery/devin-gen/exa/language_server_pb/language_server_pb.d.ts +9048 -0
  28. package/dist/types/discovery/devin-gen/exa/opensearch_clients_pb/opensearch_clients_pb.d.ts +1760 -0
  29. package/dist/types/discovery/devin-gen/exa/prompt_pb/prompt_pb.d.ts +286 -0
  30. package/dist/types/discovery/devin-gen/exa/reactive_component_pb/reactive_component_pb.d.ts +405 -0
  31. package/dist/types/discovery/devin-gen/exa/trust_pb/trust_pb.d.ts +582 -0
  32. package/dist/types/discovery/devin.d.ts +24 -0
  33. package/dist/types/discovery/gemini.d.ts +25 -0
  34. package/dist/types/discovery/gitlab-duo-workflow.d.ts +30 -0
  35. package/dist/types/discovery/index.d.ts +5 -0
  36. package/dist/types/discovery/openai-compatible.d.ts +89 -0
  37. package/dist/types/effort.d.ts +10 -0
  38. package/dist/types/fireworks-model-id.d.ts +23 -0
  39. package/dist/types/hosts.d.ts +164 -0
  40. package/dist/types/identity/bundled.d.ts +3 -0
  41. package/dist/types/identity/classify.d.ts +69 -0
  42. package/dist/types/identity/dialect.d.ts +3 -0
  43. package/dist/types/identity/family.d.ts +210 -0
  44. package/dist/types/identity/id.d.ts +12 -0
  45. package/dist/types/identity/index.d.ts +8 -0
  46. package/dist/types/identity/markers.d.ts +4 -0
  47. package/dist/types/identity/priority.d.ts +1 -0
  48. package/dist/types/identity/reference.d.ts +29 -0
  49. package/dist/types/index.d.ts +17 -0
  50. package/dist/types/model-cache.d.ts +23 -0
  51. package/dist/types/model-manager.d.ts +77 -0
  52. package/dist/types/model-thinking.d.ts +66 -0
  53. package/dist/types/models.d.ts +14 -0
  54. package/dist/types/openai-pricing.d.ts +17 -0
  55. package/dist/types/provider-models/bundled-references.d.ts +13 -0
  56. package/dist/types/provider-models/cache-provider-id.d.ts +9 -0
  57. package/dist/types/provider-models/descriptor-types.d.ts +76 -0
  58. package/dist/types/provider-models/descriptors.d.ts +504 -0
  59. package/dist/types/provider-models/google.d.ts +27 -0
  60. package/dist/types/provider-models/index.d.ts +7 -0
  61. package/dist/types/provider-models/ollama.d.ts +22 -0
  62. package/dist/types/provider-models/openai-compat.d.ts +644 -0
  63. package/dist/types/provider-models/special.d.ts +53 -0
  64. package/dist/types/types.d.ts +830 -0
  65. package/dist/types/utils.d.ts +20 -0
  66. package/dist/types/variant-collapse.d.ts +133 -0
  67. package/dist/types/wire/alibaba-token-plan.d.ts +22 -0
  68. package/dist/types/wire/codex.d.ts +45 -0
  69. package/dist/types/wire/coreweave.d.ts +12 -0
  70. package/dist/types/wire/gemini-headers.d.ts +62 -0
  71. package/dist/types/wire/github-copilot.d.ts +47 -0
  72. package/package.json +101 -100
  73. package/src/compat/openai.ts +54 -11
  74. package/src/discovery/codex.ts +3 -1
  75. package/src/hosts.ts +1 -1
  76. package/src/identity/family.ts +47 -1
  77. package/src/model-thinking.ts +30 -5
  78. package/src/models.json +2834 -810
  79. package/src/openai-pricing.ts +29 -0
  80. package/src/provider-models/cache-provider-id.ts +14 -0
  81. package/src/provider-models/descriptors.ts +3 -3
  82. package/src/provider-models/openai-compat.ts +117 -53
  83. package/src/types.ts +15 -0
  84. package/src/wire/codex.ts +3 -0
  85. package/src/wire/github-copilot.ts +32 -0
@@ -16,6 +16,7 @@ import {
16
16
  isDeepseekModelIdOrName,
17
17
  isGlm52ReasoningEffortModelId,
18
18
  isGrokReasoningEffortCapable,
19
+ isGrokXHighEffortCapable,
19
20
  isKimiK3ModelId,
20
21
  isKimiK26ModelId,
21
22
  isKimiModelId,
@@ -177,6 +178,22 @@ const MIMO_REASONING_EFFORT_MAP: NonNullable<OpenAICompat["reasoningEffortMap"]>
177
178
  xhigh: "high",
178
179
  };
179
180
 
181
+ /** Shared `minimal → low` clamp. xhigh-capable Grok keeps `xhigh` unmapped. */
182
+ const XAI_RESPONSES_MINIMAL_EFFORT_MAP: NonNullable<OpenAICompat["reasoningEffortMap"]> = {
183
+ minimal: "low",
184
+ };
185
+ /** Grok 4.5 / 4.3 / 3-mini: leftover `xhigh`/`max` clamp to `high`. */
186
+ const XAI_RESPONSES_CLAMPED_EFFORT_MAP: NonNullable<OpenAICompat["reasoningEffortMap"]> = {
187
+ minimal: "low",
188
+ xhigh: "high",
189
+ max: "high",
190
+ };
191
+
192
+ /** Wire effort remap for first-party xAI Responses. */
193
+ export function xaiResponsesReasoningEffortMap(modelId: string): NonNullable<OpenAICompat["reasoningEffortMap"]> {
194
+ return isGrokXHighEffortCapable(modelId) ? XAI_RESPONSES_MINIMAL_EFFORT_MAP : XAI_RESPONSES_CLAMPED_EFFORT_MAP;
195
+ }
196
+
180
197
  function mergeModelReasoningEffortMap(
181
198
  compat: ResolvedOpenAISharedCompat,
182
199
  modelId: string,
@@ -471,6 +488,8 @@ export function buildOpenAICompat(spec: ModelSpec<"openai-completions">): Resolv
471
488
  // OpenAI proprietary reasoning models (o-series, gpt-5+) reject explicit
472
489
  // temperature/top_p/… with a 400 on every serving host (#5606).
473
490
  supportsSamplingParams: !isOpenAISamplingRestrictedModelId(spec.id),
491
+ // xAI reasoning models 400 on presence/frequency penalties and stop.
492
+ supportsPenaltyAndStopParams: !(isGrok && Boolean(spec.reasoning)),
474
493
  reasoningEffortMap: {},
475
494
  supportsUsageInStreaming: !isCerebras,
476
495
  // Kimi (including via OpenRouter and Fireworks router-form IDs such as
@@ -684,34 +703,46 @@ export function buildOpenAIResponsesCompat(spec: OpenAIResponsesSpecLike): Resol
684
703
  const isLocalServingBackend =
685
704
  (!PROXY_OPENAI_COMPAT_PROVIDERS.has(spec.provider) && LOCAL_OPENAI_COMPAT_PROVIDERS.has(spec.provider)) ||
686
705
  hasLocalLoopbackBaseUrl(baseUrl);
706
+ const isXaiHost = modelMatchesHost({ provider: spec.provider, baseUrl }, "xai");
687
707
 
688
708
  const compat: ResolvedOpenAIResponsesCompat = {
689
709
  supportsDeveloperRole: isAzure || isOpenAIUrl || hostMatchesUrl(baseUrl, "githubCopilot"),
690
710
  supportsStrictMode: isAzure || detectStrictModeSupport(spec.provider, baseUrl),
691
- supportsReasoningEffort: spec.provider !== "xai-oauth" || isGrokReasoningEffortCapable(id),
711
+ // Paid `xai` and SuperGrok `xai-oauth` share api.x.ai `/v1/responses`.
712
+ // Only the Grok effort-capable allowlist accepts `reasoning.effort`;
713
+ // other reasoners (grok-build, grok-code-fast-1, …) 400 if it is sent.
714
+ supportsReasoningEffort: !isXaiHost || isGrokReasoningEffortCapable(id),
692
715
  supportsLongPromptCacheRetention: isOpenAIUrl,
693
716
  supportsPromptCacheBreakpoints,
694
717
  promptCacheBreakpointTtl: supportsPromptCacheBreakpoints ? "30m" : undefined,
695
718
  // Azure OpenAI and GitHub Copilot Responses paths require tool results
696
719
  // to strictly match prior tool calls when building Responses inputs.
697
720
  strictResponsesPairing: isAzure || spec.provider === "github-copilot",
698
- // GitHub Copilot and xAI OAuth reject `detail: "original"` (400 / 422).
699
- // Every other host preserves native-resolution frames (snapcompact relies
700
- // on `original`). Detect Copilot by provider id or base-URL host so a
701
- // model pointed at the Copilot host under a different provider id still
702
- // clamps; xai-oauth is provider-id only (same host family as paid `xai`).
721
+ // GitHub Copilot and first-party xAI `/v1/responses` reject
722
+ // `detail: "original"` (400 / 422). Every other host preserves
723
+ // native-resolution frames (snapcompact relies on `original`). Detect
724
+ // Copilot by provider id or base-URL host so a model pointed at the
725
+ // Copilot host under a different provider id still clamps.
703
726
  supportsImageDetailOriginal:
704
- spec.provider !== "xai-oauth" && !modelMatchesHost({ provider: spec.provider, baseUrl }, "githubCopilot"),
705
- reasoningEffortMap: {},
727
+ !isXaiHost && !modelMatchesHost({ provider: spec.provider, baseUrl }, "githubCopilot"),
728
+ // api.x.ai rejects `reasoning.summary` (SuperGrok and paid key alike).
729
+ supportsReasoningSummary: !isXaiHost,
730
+ reasoningEffortMap: isXaiHost ? { ...xaiResponsesReasoningEffortMap(id) } : {},
706
731
  supportsReasoningParams: true,
707
732
  // OpenAI proprietary reasoning models (o-series, gpt-5+) reject explicit
708
733
  // temperature/top_p/… with a 400 on every serving host (#5606).
709
734
  supportsSamplingParams: !isOpenAISamplingRestrictedModelId(id),
735
+ // xAI `/v1/responses` rejects presence/frequency penalties for every
736
+ // model, not only reasoners (https://docs.x.ai/developers/rest-api-reference/inference/chat).
737
+ supportsPenaltyAndStopParams: !isXaiHost,
710
738
  thinkingFormat,
711
739
  reasoningDisableMode: resolveReasoningDisableMode(thinkingFormat),
712
740
  omitReasoningEffort: false,
713
- includeEncryptedReasoning: spec.provider !== "xai-oauth",
714
- filterReasoningHistory: spec.provider === "xai-oauth" || (isOpenRouter && isAnthropicModel),
741
+ // Ask xAI `/v1/responses` for `reasoning.encrypted_content` and replay
742
+ // those items on later turns. OpenRouter Anthropic still filters
743
+ // reasoning wrappers independently.
744
+ includeEncryptedReasoning: true,
745
+ filterReasoningHistory: isOpenRouter && isAnthropicModel,
715
746
  disableReasoningOnForcedToolChoice: isKimiModel,
716
747
  disableReasoningOnToolChoice: isDeepseekFamily && reasoningCapable && !isOpenRouter,
717
748
  supportsToolChoice: true,
@@ -752,13 +783,24 @@ export function buildOpenAIResponsesCompat(spec: OpenAIResponsesSpecLike): Resol
752
783
  MINIMAX_PROVIDER_OR_ID_PATTERN.test(spec.provider) || (id ? MINIMAX_PROVIDER_OR_ID_PATTERN.test(id) : false),
753
784
  emptyLengthFinishIsContextError: spec.provider === "ollama",
754
785
  usesOpenAIToolCallIdLimit: spec.provider === "openai",
755
- promptCacheSessionHeader: spec.provider === "xai-oauth" ? "x-grok-conv-id" : undefined,
786
+ promptCacheSessionHeader: isXaiHost ? "x-grok-conv-id" : undefined,
756
787
  streamFirstEventTimeoutMs: isLocalServingBackend ? 0 : spec.compat?.streamFirstEventTimeoutMs,
757
788
  streamIdleTimeoutMs: isLocalServingBackend
758
789
  ? LOCAL_OPENAI_COMPAT_STREAM_IDLE_TIMEOUT_MS
759
790
  : spec.compat?.streamIdleTimeoutMs,
760
791
  };
761
792
  applyCompatOverrides(compat, spec.compat);
793
+ if (isXaiHost) {
794
+ const canonical = xaiResponsesReasoningEffortMap(id);
795
+ compat.reasoningEffortMap = { ...compat.reasoningEffortMap, ...canonical };
796
+ // xhigh-capable Grok advertises unmapped `xhigh`; drop a stale clamp
797
+ // from previous snapshots so 4.6 / 16-agent mode is not rewritten to `high`.
798
+ for (const key of ["xhigh", "max"] as const) {
799
+ if (!(key in canonical)) {
800
+ delete compat.reasoningEffortMap[key];
801
+ }
802
+ }
803
+ }
762
804
  if (spec.compat?.reasoningDisableMode === undefined) {
763
805
  compat.reasoningDisableMode = resolveReasoningDisableMode(compat.thinkingFormat);
764
806
  }
@@ -776,6 +818,7 @@ function pickResponsesOnly(compat: ResolvedOpenAIResponsesCompat): ResponsesOnly
776
818
  strictResponsesPairing: compat.strictResponsesPairing,
777
819
  supportsImageDetailOriginal: compat.supportsImageDetailOriginal,
778
820
  supportsObfuscationOptOut: compat.supportsObfuscationOptOut,
821
+ supportsReasoningSummary: compat.supportsReasoningSummary,
779
822
  isVercelGatewayHost: compat.isVercelGatewayHost,
780
823
  } satisfies ResponsesOnlyCompat;
781
824
  }
@@ -1,5 +1,6 @@
1
1
  import { type } from "@linxiraos/pi-omptype";
2
2
  import { parseKnownModel, semverEqual } from "../identity/classify";
3
+ import { resolveOpenAIDaybreakStandardCost } from "../openai-pricing";
3
4
  import type { FetchImpl, ModelSpec } from "../types";
4
5
  import { discoveryFetch } from "../utils";
5
6
  import { CODEX_BASE_URL, CODEX_CLIENT_VERSION, OPENAI_HEADER_VALUES, OPENAI_HEADERS } from "../wire/codex";
@@ -237,6 +238,7 @@ function normalizeCodexModelEntry(entry: unknown, baseUrl: string): NormalizedCo
237
238
  const preferWebsockets = toBoolean(payload.prefer_websockets) === true;
238
239
  const useResponsesLite = toBoolean(payload.use_responses_lite) === true;
239
240
  const priority = toFiniteNumber(payload.priority) ?? Number.MAX_SAFE_INTEGER;
241
+ const daybreakCost = resolveOpenAIDaybreakStandardCost(slug);
240
242
 
241
243
  return {
242
244
  priority,
@@ -248,7 +250,7 @@ function normalizeCodexModelEntry(entry: unknown, baseUrl: string): NormalizedCo
248
250
  baseUrl,
249
251
  reasoning,
250
252
  input,
251
- cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
253
+ cost: daybreakCost ? { ...daybreakCost } : { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
252
254
  remoteCompaction: CODEX_REMOTE_COMPACTION,
253
255
  contextWindow,
254
256
  maxTokens,
package/src/hosts.ts CHANGED
@@ -47,7 +47,7 @@ export const KNOWN_HOSTS = {
47
47
  },
48
48
  umans: { providers: ["umans"], urlMarkers: ["api.code.umans.ai"] },
49
49
  xiaomi: { providers: ["xiaomi"], providerPrefixes: ["xiaomi-token-plan-"], urlMarkers: ["xiaomimimo.com"] },
50
- xai: { providers: ["xai"], urlMarkers: ["api.x.ai"] },
50
+ xai: { providers: ["xai", "xai-oauth"], urlMarkers: ["api.x.ai"] },
51
51
  mistral: { providers: ["mistral"], urlMarkers: ["mistral.ai"] },
52
52
  together: { providers: ["together"], urlMarkers: ["api.together.xyz"] },
53
53
  baseten: { providers: ["baseten"], urlMarkers: ["baseten.co"] },
@@ -110,7 +110,13 @@ export const isGrokModelId = memo((modelId: string): boolean => {
110
110
  return /(?:^|[./_-])grok(?:[-.]|$)/i.test(modelId);
111
111
  });
112
112
 
113
- const GROK_EFFORT_CAPABLE_PREFIXES = ["grok-3-mini", "grok-4.20-multi-agent", "grok-4.3", "grok-4.5"] as const;
113
+ const GROK_EFFORT_CAPABLE_PREFIXES = [
114
+ "grok-3-mini",
115
+ "grok-4.20-multi-agent",
116
+ "grok-4.3",
117
+ "grok-4.5",
118
+ "grok-4.6",
119
+ ] as const;
114
120
 
115
121
  /**
116
122
  * Grok SKUs that expose the wire `reasoning.effort` dial. Other Grok reasoners
@@ -123,6 +129,27 @@ export const isGrokReasoningEffortCapable = memo((modelId: string): boolean => {
123
129
  return GROK_EFFORT_CAPABLE_PREFIXES.some(prefix => bare.startsWith(prefix));
124
130
  });
125
131
 
132
+ /**
133
+ * `grok-4.20-multi-agent*` uses `reasoning.effort` to pick agent count
134
+ * (`xhigh` is the 16-agent mode). Other first-party Grok effort SKUs stay on
135
+ * `low|medium|high` unless {@link isGrokXHighEffortCapable} (currently
136
+ * `grok-4.6*` plus multi-agent).
137
+ * https://docs.x.ai/developers/model-capabilities/text/reasoning
138
+ */
139
+ export const isGrokMultiAgentModelId = memo((modelId: string): boolean => {
140
+ return bareModelId(modelId).trim().toLowerCase().startsWith("grok-4.20-multi-agent");
141
+ });
142
+
143
+ /**
144
+ * First-party Grok SKUs whose Responses wire accepts `reasoning.effort: "xhigh"`.
145
+ * `grok-4.6*` documents xhigh as a reasoning depth; multi-agent uses it as
146
+ * 16-agent mode. `grok-4.5` / `grok-4.3` / `grok-3-mini` do not.
147
+ */
148
+ export const isGrokXHighEffortCapable = memo((modelId: string): boolean => {
149
+ if (isGrokMultiAgentModelId(modelId)) return true;
150
+ return bareModelId(modelId).trim().toLowerCase().startsWith("grok-4.6");
151
+ });
152
+
126
153
  /**
127
154
  * MiniMax M2-generation family (M2, M2.1, M2.5, M2.7, including `-highspeed`/
128
155
  * `-lightning`/`-her`/`-turbo` variants, dotless aliases like `minimax-m21`,
@@ -251,6 +278,25 @@ export const isGlm52ReasoningEffortModelId = memo((modelId: string): boolean =>
251
278
  return semverGte(glm.version, "5.2");
252
279
  });
253
280
 
281
+ /**
282
+ * GLM-5.3+ coding SKUs. Unlike GLM-5.2 (whose reasoning_effort dialect is
283
+ * host-specific), GLM-5.3+ exposes a uniform wire-exact `low`/`high`/`max`
284
+ * ladder on every host, and thinking can no longer be disabled —
285
+ * `thinking.type` must always be `enabled`. Matching the family keeps future
286
+ * bumps (`glm-5.4`, `glm-6`, …) covered while excluding the vision (`…v`)
287
+ * shape and the non-reasoning `-flash`/`-flashx`/`-preview` variants.
288
+ */
289
+ export const isGlm53ReasoningEffortModelId = memo((modelId: string): boolean => {
290
+ const glm = parseGlmModel(bareModelId(modelId));
291
+ if (!glm || glm.vision) {
292
+ return false;
293
+ }
294
+ if (glm.variant !== "base" && glm.variant !== "air" && glm.variant !== "turbo") {
295
+ return false;
296
+ }
297
+ return semverGte(glm.version, "5.3");
298
+ });
299
+
254
300
  /** GLM vision SKUs — the `v` that attaches to the version (`glm-4v`, `glm-4.5v`). */
255
301
  export const isGlmVisionModelId = memo((modelId: string): boolean => {
256
302
  return parseGlmModel(bareModelId(modelId))?.vision === true;
@@ -26,6 +26,8 @@ import {
26
26
  isDeepseekModelIdOrName,
27
27
  isDeepseekV4FlashModelId,
28
28
  isGlm52ReasoningEffortModelId,
29
+ isGlm53ReasoningEffortModelId,
30
+ isGrokXHighEffortCapable,
29
31
  isKimiK3ModelId,
30
32
  isMimoModelIdOrName,
31
33
  isMinimaxM2FamilyModelId,
@@ -178,7 +180,8 @@ function fillThinkingWireDefaults<TApi extends Api>(
178
180
  (spec.api === "anthropic-messages" || spec.api === "bedrock-converse-stream") &&
179
181
  supportsAdaptiveThinkingDisplay(spec.id);
180
182
  const needsRequiresEffort = thinking.requiresEffort === undefined && impliesMandatoryReasoning(parsed, spec.id);
181
- const needsDefaultLevel = thinking.defaultLevel === undefined && isKimiK3ModelId(spec.id);
183
+ const needsDefaultLevel =
184
+ thinking.defaultLevel === undefined && (isKimiK3ModelId(spec.id) || isGlm53ReasoningEffortModelId(spec.id));
182
185
  if (!effortsChanged && !shouldReplaceEffortMap && !needsDisplay && !needsRequiresEffort && !needsDefaultLevel) {
183
186
  return thinking;
184
187
  }
@@ -216,7 +219,7 @@ export function deriveThinking<TApi extends Api>(spec: ModelSpec<TApi>, compat:
216
219
  mode: inferThinkingControlMode(spec, parsed),
217
220
  efforts,
218
221
  };
219
- if (isKimiK3ModelId(spec.id)) {
222
+ if (isKimiK3ModelId(spec.id) || isGlm53ReasoningEffortModelId(spec.id)) {
220
223
  config.defaultLevel = Effort.Max;
221
224
  }
222
225
  const effortMap = inferEffortMap(spec, compat, config.mode, config.efforts);
@@ -312,6 +315,13 @@ function getModelDefinedEfforts<TApi extends Api>(
312
315
  spec: ModelSpec<TApi>,
313
316
  compat: CompatOf<TApi>,
314
317
  ): readonly Effort[] | undefined {
318
+ if (isGlm53ReasoningEffortModelId(spec.id)) {
319
+ // GLM-5.3+ exposes a uniform wire-exact low/high/max ladder on every
320
+ // host — unlike GLM-5.2, whose reasoning_effort dialect is
321
+ // host-specific. Thinking can no longer be disabled (handled by
322
+ // impliesMandatoryReasoning), and the default effort is `max`.
323
+ return LOW_HIGH_MAX_REASONING_EFFORTS;
324
+ }
315
325
  if (isGlm52ReasoningEffortModelId(spec.id)) {
316
326
  // GLM-5.2's reasoning_effort dialect is host-specific (verified against
317
327
  // live endpoints):
@@ -374,13 +384,20 @@ function getModelDefinedEfforts<TApi extends Api>(
374
384
  // on every first-party/aggregator host — the direct API, aggregators, and
375
385
  // Ollama Cloud alike (medium/xhigh fold into high, max is a real wire
376
386
  // tier). See https://api-docs.deepseek.com/api/create-chat-completion.
377
- // OpenRouter's non-Flash V4 route still exposes only high; the older
378
- // reasoners (V3.x, R1, deepseek-reasoner) top out at high/max.
387
+ // OpenRouter's non-Flash V4 route exposes only high, except the dated
388
+ // `deepseek-v4-pro-0813` SKU: its /models metadata advertises (and the
389
+ // route accepts) the full low/high/max ladder like every other host.
390
+ // The older reasoners (V3.x, R1, deepseek-reasoner) top out at high/max.
379
391
  if (isDeepseekV4FlashModelId(spec.id)) {
380
392
  return LOW_HIGH_MAX_REASONING_EFFORTS;
381
393
  }
382
394
  if (bareModelId(spec.id).toLowerCase().includes("deepseek-v4")) {
383
- return isOpenRouterThinkingFormat(compat) ? HIGH_ONLY_REASONING_EFFORTS : LOW_HIGH_MAX_REASONING_EFFORTS;
395
+ if (!isOpenRouterThinkingFormat(compat)) {
396
+ return LOW_HIGH_MAX_REASONING_EFFORTS;
397
+ }
398
+ return bareModelId(spec.id).toLowerCase() === "deepseek-v4-pro-0813"
399
+ ? LOW_HIGH_MAX_REASONING_EFFORTS
400
+ : HIGH_ONLY_REASONING_EFFORTS;
384
401
  }
385
402
  return isOpenRouterThinkingFormat(compat) ? HIGH_ONLY_REASONING_EFFORTS : HIGH_MAX_REASONING_EFFORTS;
386
403
  }
@@ -388,6 +405,11 @@ function getModelDefinedEfforts<TApi extends Api>(
388
405
  // Baseten's gpt-oss router mirrors its GLM route: high/max only.
389
406
  return HIGH_MAX_REASONING_EFFORTS;
390
407
  }
408
+ // First-party Grok: `grok-4.6*` and `grok-4.20-multi-agent*` advertise
409
+ // `xhigh`. Other effort-capable SKUs stay on `minimal/low/medium/high`.
410
+ if (modelMatchesHost({ provider: spec.provider, baseUrl: spec.baseUrl ?? "" }, "xai")) {
411
+ return isGrokXHighEffortCapable(spec.id) ? DEFAULT_REASONING_EFFORTS_WITH_XHIGH : DEFAULT_REASONING_EFFORTS;
412
+ }
391
413
  return isOpenAICompatReasoningApi(spec.api) &&
392
414
  (isMinimaxM2FamilyModelId(spec.id) ||
393
415
  isOpenAIGptOssModelId(spec.id) ||
@@ -572,6 +594,9 @@ function impliesMandatoryReasoning(parsed: ParsedModel, modelId: string): boolea
572
594
  if (parsed.kind === "pro" && semverGte(parsed.version, "2.5")) return true;
573
595
  }
574
596
  if (isKimiK3ModelId(modelId)) return true;
597
+ // GLM-5.3+ no longer supports disabling thinking — thinking.type must
598
+ // always be "enabled". Floor thinking-off requests to the lowest effort.
599
+ if (isGlm53ReasoningEffortModelId(modelId)) return true;
575
600
  if (isMinimaxM2FamilyModelId(modelId)) return true;
576
601
  if (OPENAI_O_SERIES_RE.test(bareModelId(modelId))) return true;
577
602
  return findThinkingVariantToken(modelId) !== undefined;